Problem Description¶
The GeoAI ground-level NO2 estimation challenge will ask participants to develop ML models to estimate surface NO2 concentrations using only public remote sensing data as predictor variables. Participants will be provided with ground truth data from air quality monitoring stations and remote sensing data processed by Google Earth Engine (GEE). The challenge encourages participants to explore innovative approaches to NO2 monitoring and modelling, while emphasising simplicity, reproducibility, and transparency in their methodologies. Participants will need to test their models not only in general terms, but also spatially over the study area and temporally over the year, and be able to interpret the given results.
The data is:
-Ground-truth data from air quality monitoring stations in the continental part of Lombardy and Veneto regions. -Remote sensing data of NO2 from Sentinel-5P TROPOMI, precipitation from CHIRPS and land surface temperature from NOAA datasets, all from Google Earth Engine (GEE).
# Importación de librerías estándar
import os
import math
import time
from datetime import datetime
# Importación de librerías para procesamiento de datos
import numpy as np
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point
# Importación de librerías para visualización
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns
# Importación de librerías de tqdm para el progreso
from tqdm.notebook import tqdm
from tqdm import tqdm
# Importación de librerías de scikit-learn para preprocesamiento y modelado
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
from sklearn.linear_model import BayesianRidge
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, MinMaxScaler, scale
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.ensemble import RandomForestRegressor, ExtraTreesRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.tree import DecisionTreeRegressor
from sklearn.inspection import PartialDependenceDisplay
from scikeras.wrappers import KerasRegressor
from keras_tuner import Hyperband
from keras.callbacks import EarlyStopping
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import BaggingRegressor
# Importación de librerías adicionales
import pycaret
import xgboost as xgb
1. Recolección de data¶
#Cargar data
train = pd.read_csv("/Users/carlazurcher/Downloads/geoai-ground-level-no2-estimation-challenge20240612-4943-16iro0r/Train.csv")
train.head(10)
| ID_Zindi | Date | ID | LAT | LON | Precipitation | LST | AAI | CloudFraction | NO2_strat | NO2_total | NO2_trop | TropopausePressure | GT_NO2 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ID_ENTGC7 | 1/1/19 | PD01 | 45.601585 | 11.903551 | 0.000000 | NaN | 0.230527 | 0.559117 | 0.000024 | 0.000117 | NaN | 14440.82126 | 31.0 |
| 1 | ID_8JCCXC | 1/1/19 | PD04 | 45.371005 | 11.840830 | 3.047342 | NaN | -0.074006 | 0.869309 | 0.000024 | 0.000127 | NaN | 14441.79815 | 42.0 |
| 2 | ID_V3136Z | 1/1/19 | RO01 | 45.045825 | 12.060869 | 0.000000 | NaN | 0.024470 | 0.674160 | 0.000024 | 0.000086 | NaN | 14437.38294 | 31.0 |
| 3 | ID_KRVZDJ | 1/1/19 | RO02 | 45.104075 | 11.553241 | 1.200467 | NaN | -0.010442 | 0.920054 | 0.000024 | 0.000124 | NaN | 14440.83831 | 30.0 |
| 4 | ID_PR351A | 1/1/19 | RO03 | 45.038758 | 11.790152 | 1.274564 | NaN | -0.176178 | 0.747464 | 0.000024 | 0.000116 | NaN | 14438.79037 | 58.0 |
| 5 | ID_4XN0K8 | 1/1/19 | TV01 | 45.889734 | 12.307124 | 0.000000 | 278.38 | -0.366831 | 0.324392 | 0.000023 | 0.000109 | NaN | 14432.05624 | 26.0 |
| 6 | ID_O0RJKX | 1/1/19 | TV02 | 45.671721 | 12.237807 | 0.000000 | NaN | 0.188599 | 0.818422 | 0.000024 | 0.000135 | NaN | 14436.70176 | 38.0 |
| 7 | ID_1APJEY | 1/1/19 | VE01 | 45.629092 | 12.590682 | 0.000000 | NaN | 0.507837 | 0.926018 | 0.000024 | 0.000137 | NaN | 14435.01960 | 34.0 |
| 8 | ID_4B1H1U | 1/1/19 | VE02 | 45.499618 | 12.261249 | 0.000000 | NaN | 0.087363 | 0.835097 | 0.000024 | 0.000104 | NaN | 14438.51425 | 41.0 |
| 9 | ID_3JD1GC | 1/1/19 | VE03 | 45.428424 | 12.312930 | 0.650355 | NaN | 0.208678 | 0.812696 | 0.000024 | 0.000117 | NaN | 14437.71015 | 35.0 |
2. Limpiar datos¶
#Observar caracteristicas de los datos
train.describe()
| LAT | LON | Precipitation | LST | AAI | CloudFraction | NO2_strat | NO2_total | NO2_trop | TropopausePressure | GT_NO2 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 86584.000000 | 86584.000000 | 86584.000000 | 46798.000000 | 73709.000000 | 73709.000000 | 73709.000000 | 73709.000000 | 51111.000000 | 73709.000000 | 82051.000000 |
| mean | 45.421456 | 10.014272 | 2.585528 | 299.268841 | -1.274999 | 0.200606 | 0.000045 | 0.000156 | 0.000105 | 16655.112392 | 24.535051 |
| std | 0.225409 | 1.056637 | 7.617394 | 10.927167 | 0.693003 | 0.259607 | 0.000012 | 0.000103 | 0.000092 | 3000.748790 | 17.108838 |
| min | 44.924694 | 8.736497 | 0.000000 | 253.200000 | -5.196266 | 0.000000 | 0.000013 | -0.000012 | -0.000025 | 8614.349685 | 0.000000 |
| 25% | 45.249544 | 9.195325 | 0.000000 | 290.920000 | -1.749425 | 0.023900 | 0.000034 | 0.000100 | 0.000047 | 14432.114060 | 11.875000 |
| 50% | 45.478996 | 9.611738 | 0.000000 | 300.760000 | -1.349746 | 0.078478 | 0.000047 | 0.000122 | 0.000071 | 16711.190570 | 20.000000 |
| 75% | 45.601232 | 10.683357 | 0.000000 | 307.940000 | -0.878857 | 0.278451 | 0.000056 | 0.000173 | 0.000129 | 19252.648570 | 33.050000 |
| max | 45.889734 | 12.590682 | 135.396805 | 327.840000 | 2.143020 | 1.000000 | 0.000073 | 0.002047 | 0.001097 | 24449.007150 | 188.233333 |
- Precipitation y GT_NO2 tiene un valor max muy alejado del resto del 75% de los datos. Se debe investigar más sobre el comportamietno de estos valores
#Verifico data type
train.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 86584 entries, 0 to 86583 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID_Zindi 86584 non-null object 1 Date 86584 non-null object 2 ID 86584 non-null object 3 LAT 86584 non-null float64 4 LON 86584 non-null float64 5 Precipitation 86584 non-null float64 6 LST 46798 non-null float64 7 AAI 73709 non-null float64 8 CloudFraction 73709 non-null float64 9 NO2_strat 73709 non-null float64 10 NO2_total 73709 non-null float64 11 NO2_trop 51111 non-null float64 12 TropopausePressure 73709 non-null float64 13 GT_NO2 82051 non-null float64 dtypes: float64(11), object(3) memory usage: 9.2+ MB
#Verifico que ID_Zindi no tenga duplicados
duplicates = train[train.duplicated(subset=['ID_Zindi'], keep=False)]
# Print duplicados
print("Duplicates in column '{}' are:".format('ID_Zindi'))
print(duplicates)
Duplicates in column 'ID_Zindi' are:
ID_Zindi Date ID LAT LON Precipitation \
27049 ID_LMYYAX 9/12/19 X30163 45.513039 10.191942 0.0
58817 ID_ZHFIGQ 14-01-21 X5547 45.551042 9.162614 0.0
72174 ID_LMYYAX 2/7/21 X5579 45.697952 9.406191 0.0
81055 ID_ZHFIGQ 23-10-21 PD04 45.371005 11.840830 0.0
LST AAI CloudFraction NO2_strat NO2_total NO2_trop \
27049 NaN -1.045318 0.720345 0.000030 0.000288 NaN
58817 283.32 -1.443808 0.014917 0.000023 0.000352 0.000329
72174 315.06 -0.240127 0.035781 0.000062 0.000114 0.000052
81055 294.90 -0.837195 0.075230 0.000041 0.000144 0.000103
TropopausePressure GT_NO2
27049 22190.99169 49.275
58817 14423.64429 72.200
72174 19243.52026 25.200
81055 16734.66441 23.000
# Drop la primera entrada de filas duplicadas
index_to_drop = [27049,58817]
train.drop(index=index_to_drop, inplace=True)
#Corregir formato de fecha mixto (algunos poseen / otros -)
train['Date'] = train['Date'].str.replace('/', '-')
#Corregir fecha a datetime
train['Date']=pd.to_datetime(train['Date'],format='%d-%m-%y', dayfirst=True)
train['Date']
0 2019-01-01
1 2019-01-01
2 2019-01-01
3 2019-01-01
4 2019-01-01
...
86579 2021-12-31
86580 2021-12-31
86581 2021-12-31
86582 2021-12-31
86583 2021-12-31
Name: Date, Length: 86582, dtype: datetime64[ns]
#Verifico resultados
train.info()
<class 'pandas.core.frame.DataFrame'> Index: 86582 entries, 0 to 86583 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID_Zindi 86582 non-null object 1 Date 86582 non-null datetime64[ns] 2 ID 86582 non-null object 3 LAT 86582 non-null float64 4 LON 86582 non-null float64 5 Precipitation 86582 non-null float64 6 LST 46797 non-null float64 7 AAI 73707 non-null float64 8 CloudFraction 73707 non-null float64 9 NO2_strat 73707 non-null float64 10 NO2_total 73707 non-null float64 11 NO2_trop 51110 non-null float64 12 TropopausePressure 73707 non-null float64 13 GT_NO2 82049 non-null float64 dtypes: datetime64[ns](1), float64(11), object(2) memory usage: 9.9+ MB
#Paso ID a index
train.set_index('ID_Zindi', inplace=True)
#Agrupo variables numericas
train_numeric= train.select_dtypes(include=['number'])
train_numeric
| LAT | LON | Precipitation | LST | AAI | CloudFraction | NO2_strat | NO2_total | NO2_trop | TropopausePressure | GT_NO2 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| ID_Zindi | |||||||||||
| ID_ENTGC7 | 45.601585 | 11.903551 | 0.000000 | NaN | 0.230527 | 0.559117 | 0.000024 | 0.000117 | NaN | 14440.82126 | 31.000 |
| ID_8JCCXC | 45.371005 | 11.840830 | 3.047342 | NaN | -0.074006 | 0.869309 | 0.000024 | 0.000127 | NaN | 14441.79815 | 42.000 |
| ID_V3136Z | 45.045825 | 12.060869 | 0.000000 | NaN | 0.024470 | 0.674160 | 0.000024 | 0.000086 | NaN | 14437.38294 | 31.000 |
| ID_KRVZDJ | 45.104075 | 11.553241 | 1.200467 | NaN | -0.010442 | 0.920054 | 0.000024 | 0.000124 | NaN | 14440.83831 | 30.000 |
| ID_PR351A | 45.038758 | 11.790152 | 1.274564 | NaN | -0.176178 | 0.747464 | 0.000024 | 0.000116 | NaN | 14438.79037 | 58.000 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| ID_NCWXIY | 45.498227 | 9.556232 | 0.000000 | NaN | -0.434350 | 0.250490 | 0.000032 | 0.000643 | NaN | 13063.79770 | 39.750 |
| ID_UDQIEE | 45.142541 | 10.043836 | 0.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 30.125 |
| ID_ENDUPX | 45.842207 | 9.351658 | 0.000000 | 284.98 | -0.157753 | 0.000000 | 0.000031 | 0.000153 | 0.000122 | 13050.16499 | 28.325 |
| ID_3ZBA6C | 45.113503 | 8.874065 | 0.000000 | NaN | -0.798636 | 0.399524 | 0.000031 | 0.000717 | NaN | 13061.41329 | 21.250 |
| ID_GWG0LD | 45.526473 | 9.515980 | 0.000000 | NaN | -0.434482 | 0.250530 | 0.000032 | 0.000643 | NaN | 13063.79500 | 40.350 |
86582 rows × 11 columns
3. EDA Analisis exploratorio de datos¶
3.1 Reporte a profunidad¶
Hay varias variables con altos porcentajes de valores missing. Esto se debe evaluar más adelante.
Hay possibles correlaciones entre varias variables. En el mapa de correlaciones se observa: Correlacion medianamente fuerte entre GT_NO2 y NO2_trop, NO2_total. Correlación negativa entre GT_NO2 y NO2_strat. Correlacion fuerte entre NO2_Trop y NO2_total. Correlacion entre NO2_strat y LST.
CloudFraction, Precipitation,NO2_total,No2_trop presentan asimetria hacia la izquierda.
import pandas_profiling
pandas_profiling.ProfileReport(train_numeric)
Summarize dataset: 0%| | 0/5 [00:00<?, ?it/s]
Generate report structure: 0%| | 0/1 [00:00<?, ?it/s]
Render HTML: 0%| | 0/1 [00:00<?, ?it/s]
3.2 Boxplot para analizar comportamientio de outliers y Kernel Density Estimate plot¶
*Precipitation, AAI, NO2_total, NO2_trop, Cloudfraction, GT_NO2 presentan outliers. En especifico Precipitation tiene la mayor parte de su población en 0, lo cual genera un comportamiento de outliers más extremo.
Modelos tree based como decision trees, random forest o gradient bosst son más resistentes a los outliers por la naturaleza en como manejan la data, por lo que será buena idea probar estos modelos más adelante.
fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(18, 12))
axes = axes.flatten()
# Generate boxplots for each numerical variable
for i, var in enumerate(train_numeric):
sns.boxplot(train_numeric[var], color='blue', ax=axes[i])
axes[i].set_title(f'Boxplot de {var}')
axes[i].set_xlabel(var)
axes[i].set_ylabel('Frecuencia')
# Hide any remaining empty subplots
if len(train_numeric) < len(axes):
for j in range(len(train_numeric), len(axes)):
axes[j].axis('off') # This hides the axis completely
plt.tight_layout()
plt.savefig('Boxplot.png')
plt.show()
KDE Plot¶
*NO2_total, No2_trop, CloudFraction y Precipitation tienen una asimetria hacia la izquierda.
*TopopausePressure presenta varios grupos marcados, los picos podrían representar diferentes climas o diferentes presiones a lo largo de las estaciones del año.
# Number of plots per row and column
n_rows, n_cols = 4, 4
# Create a figure with a 3x3 grid of subplots
fig, axes = plt.subplots(n_rows, n_cols, figsize=(15, 15))
# Flatten the axes array for easy iteration
axes = axes.flatten()
# Generate Kernel Density Plots for each numerical variable
for i, col in enumerate(train_numeric):
sns.kdeplot(train_numeric[col], shade=True, ax=axes[i])
axes[i].set_title(f'Kernel Density Plot of {col}')
axes[i].set_xlabel(col)
axes[i].set_ylabel('Density')
# Remove any empty subplots
for j in range(i + 1, n_rows * n_cols):
fig.delaxes(axes[j])
# Adjust layout
plt.tight_layout()
plt.show()
3.4 Componente de tiempo.¶
La mayoría de las variables tiene una componente estacional, se observa patrones definidos a lo largo del tiempo al rededor de los mismos meses.
#Timeseries analisis
timeseries = train_numeric.drop(['LAT', 'LON'], axis=1)
#Uno Date a train_numeric dataset
train_numeric_with_date = timeseries.merge(train[['Date']], left_index=True, right_index=True, how='left')
train_numeric_with_date
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(25, 20))
axes = axes.flatten()
for i, var in enumerate(timeseries):
axes[i].plot(train_numeric_with_date['Date'], train_numeric_with_date[var], label=var)
axes[i].set_title(f'Serie Temporal de la Concentración de {var}')
axes[i].set_xlabel('Date')
axes[i].set_ylabel(f'Concentración de {var}')
axes[i].legend()
# Esconder subplts vacios
for j in range(len(train_numeric), len(axes)):
fig.delaxes(axes[j])
plt.tight_layout()
plt.show()
3.5 Analisis de correlaciones¶
Analisis de correlacion que ya habiamos visto anteriormente con el pandas_progiling. Pero se detalla los valores en un grafico de barras horizontales para mejor apreciacion de las correlaciones con respecto a la variable objetivo GT_NO2.
No2_strat, LST tienen una correlacion media negativa con respecto a la variable objetivo.
No2_total y NO2_trop tienen correlacion fuerte positiva respecto a la variable objetivo.
missing_correlation = train_numeric.corr()
sns.heatmap(missing_correlation, cmap='coolwarm')
plt.show()
(missing_correlation
.GT_NO2
.drop('GT_NO2') # don't compare with myself
.sort_values(ascending=False)
.plot
.barh())
<Axes: >
3.7 Pair Plot¶
- Se aprecian relaciones lineales entre No2_total y No2 trop.
- Los mayores valores de GT_NO2 respecto a la variable AAI se aprecian alrededor de -1.
# Create a pairplot
sns.pairplot(train_numeric,diag_kind='kde')
plt.show()
Con el pair plot se logra observar la correlacion entre las variables NO2_total y NO2_trop, indicada en la matriz de correlacion. Se observa que es una correlación positiva, conforme aumenta el valor de una variable, aumenta el de la otra. Es importante evitar variables con correlaciones altas porque pueden introducir redundancia, dificultar la interpretación del modelo, aumentar el riesgo de sobreajuste y reducir la eficiencia computacional.¶
3.8 Geographical distribution¶
- No se aprecia nada puntual con respecto a la ubicación. Tienen valores bastante similares.
# Convert the DataFrame to a GeoDataFrame
geometry = [Point(xy) for xy in zip(train_numeric['LON'], train_numeric['LAT'])]
geo_data = gpd.GeoDataFrame(train_numeric, geometry=geometry)
# Plot the GeoDataFrame
fig, ax = plt.subplots(1, 1, figsize=(15, 15))
geo_data.plot(column='GT_NO2', ax=ax, legend=True, cmap='OrRd', markersize=100, legend_kwds={'label': "NO2 Concentration (µg/m³)"})
# Add title and labels
plt.title('Geographical Distribution of NO2 Concentrations')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
# Show the plot
plt.show()
4. Limpieza y preparación de la data¶
4.1 Separo month, date, year¶
#Uno Date a train_numeric dataset
train_numeric = train_numeric.merge(train[['Date']], left_index=True, right_index=True, how='left')
# Extraer informacion importante de datetime
train_numeric['Year'] = train_numeric['Date'].dt.year
train_numeric['Month'] = train_numeric['Date'].dt.month
train_numeric['Day'] = train_numeric['Date'].dt.day
#Eliminar date compuesta
train_numeric.drop('Date', axis=1,inplace=True)
train_numeric
| LAT | LON | Precipitation | LST | AAI | CloudFraction | NO2_strat | NO2_total | NO2_trop | TropopausePressure | GT_NO2 | Year | Month | Day | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ID_Zindi | ||||||||||||||
| ID_ENTGC7 | 45.601585 | 11.903551 | 0.000000 | NaN | 0.230527 | 0.559117 | 0.000024 | 0.000117 | NaN | 14440.82126 | 31.000 | 2019 | 1 | 1 |
| ID_8JCCXC | 45.371005 | 11.840830 | 3.047342 | NaN | -0.074006 | 0.869309 | 0.000024 | 0.000127 | NaN | 14441.79815 | 42.000 | 2019 | 1 | 1 |
| ID_V3136Z | 45.045825 | 12.060869 | 0.000000 | NaN | 0.024470 | 0.674160 | 0.000024 | 0.000086 | NaN | 14437.38294 | 31.000 | 2019 | 1 | 1 |
| ID_KRVZDJ | 45.104075 | 11.553241 | 1.200467 | NaN | -0.010442 | 0.920054 | 0.000024 | 0.000124 | NaN | 14440.83831 | 30.000 | 2019 | 1 | 1 |
| ID_PR351A | 45.038758 | 11.790152 | 1.274564 | NaN | -0.176178 | 0.747464 | 0.000024 | 0.000116 | NaN | 14438.79037 | 58.000 | 2019 | 1 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| ID_NCWXIY | 45.498227 | 9.556232 | 0.000000 | NaN | -0.434350 | 0.250490 | 0.000032 | 0.000643 | NaN | 13063.79770 | 39.750 | 2021 | 12 | 31 |
| ID_UDQIEE | 45.142541 | 10.043836 | 0.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 30.125 | 2021 | 12 | 31 |
| ID_ENDUPX | 45.842207 | 9.351658 | 0.000000 | 284.98 | -0.157753 | 0.000000 | 0.000031 | 0.000153 | 0.000122 | 13050.16499 | 28.325 | 2021 | 12 | 31 |
| ID_3ZBA6C | 45.113503 | 8.874065 | 0.000000 | NaN | -0.798636 | 0.399524 | 0.000031 | 0.000717 | NaN | 13061.41329 | 21.250 | 2021 | 12 | 31 |
| ID_GWG0LD | 45.526473 | 9.515980 | 0.000000 | NaN | -0.434482 | 0.250530 | 0.000032 | 0.000643 | NaN | 13063.79500 | 40.350 | 2021 | 12 | 31 |
86582 rows × 14 columns
4.2 Tratamiento de missings¶
Como se menciona anteriormente, con pandas_profiling, se encuentra un gran porcentaje de valores missing. LST y NO2_trop tienen % de missings muy altos. Imputar la variable objetivo puede ser problematico y no es recomendado en la literatura. Introduce bias en el modelo, por lo que se eliminan ese 5% de muestras que contienen GT_NO2 missing.
#Definicion para deteccion de missings
def missing_proport(df):
df = df.apply(lambda x: x.isna().sum()/df.shape[0]*100)
df = df.sort_values(ascending=False)
return df
#Aplico formula
missing_proport(train_numeric)
LST 45.950659 NO2_trop 40.969255 AAI 14.870296 CloudFraction 14.870296 NO2_strat 14.870296 NO2_total 14.870296 TropopausePressure 14.870296 GT_NO2 5.235499 LAT 0.000000 LON 0.000000 Precipitation 0.000000 Year 0.000000 Month 0.000000 Day 0.000000 dtype: float64
# Drop rows where 'GT_NO2' is NaN
train_numeric.dropna(subset=['GT_NO2'], inplace=True)
#Verifico Nan otra vez
missing_proport(train_numeric)
LST 45.817743 NO2_trop 40.741508 AAI 14.769223 CloudFraction 14.769223 NO2_strat 14.769223 NO2_total 14.769223 TropopausePressure 14.769223 LAT 0.000000 LON 0.000000 Precipitation 0.000000 GT_NO2 0.000000 Year 0.000000 Month 0.000000 Day 0.000000 dtype: float64
Utilizar Imputador MICE para la imputacion de missings de las demas variables (No la objetivo). Utiliza una serie de modelos de regresión, iterando sobre cada característica con datos faltantes para imputarla en función de otras variables. De utilidad cuando son varias variables con valores faltantes.
Se utilizó el estimator ExtraTreesRegressor en el proceso de imputación debido a su capacidad para capturar interacciones complejas en los datos y ser robusto frente a outliers
#Imputacion para missings de las otras variables
# Features para ser imputados
features = ['LST', 'NO2_trop', 'AAI', 'CloudFraction', 'NO2_strat', 'NO2_total', 'TropopausePressure']
# Reset index antes de normalizar
train_numeric.reset_index(inplace=True)
# Normalizar la data para un mejor manejo.
scaler_missings = MinMaxScaler()
train_numeric_scaled = scaler_missings.fit_transform(train_numeric[features])
# Convertir el array normalizado de vuelta a DataFrame
train_numeric_scaled = pd.DataFrame(train_numeric_scaled, columns=features)
# Usar la data normalziada para la imputacion
imputer = IterativeImputer(estimator=BayesianRidge())
df_imputed = imputer.fit_transform(train_numeric_scaled)
# Convertir de vuelta a dataFrame
df_imputed = pd.DataFrame(df_imputed, columns=features)
# Transformar de vuelta a escala original
df_imputed_original_scale = pd.DataFrame(scaler_missings.inverse_transform(df_imputed), columns=features)
# Reemplazar con los valores imputados
train_numeric.loc[:, features] = df_imputed_original_scale
# 'ID_Zindi' back as index
train_numeric.set_index('ID_Zindi', inplace=True)
#Verifico NaN
missing_proport(train_numeric)
LAT 0.0 LON 0.0 Precipitation 0.0 LST 0.0 AAI 0.0 CloudFraction 0.0 NO2_strat 0.0 NO2_total 0.0 NO2_trop 0.0 TropopausePressure 0.0 GT_NO2 0.0 Year 0.0 Month 0.0 Day 0.0 dtype: float64
Tratamiento outliers¶
Se aplicó el metodo IQR para tratamiento de outliers.
def iqr_outliers(df, column):
"""
Identify outliers using the IQR method.
Parameters:
- df: pandas DataFrame
- column: str, the name of the column to check for outliers
Returns:
- pandas Series, with outliers flagged as True
"""
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = (df[column] < lower_bound) | (df[column] > upper_bound)
return outliers
# Apply IQR outlier detection to all numeric columns
numeric_columns = train_numeric.select_dtypes(include=[np.number]).columns
numeric_columns = numeric_columns.drop('GT_NO2')
for column in numeric_columns:
outliers = iqr_outliers(train_numeric, column)
# You can choose to either remove these outliers or handle them in some other way
print(f"Outliers in {column}: {outliers.sum()} out of {len(train_numeric)}")
# For example, capping/flooring the outliers:
def cap_floor_outliers(df, column, lower_limit=0.01, upper_limit=0.99):
lower_quantile = df[column].quantile(lower_limit)
upper_quantile = df[column].quantile(upper_limit)
capped_values = np.where(df[column] < lower_quantile, lower_quantile,
np.where(df[column] > upper_quantile, upper_quantile, df[column]))
return capped_values
# Apply capping/flooring to all numeric columns
#Crear copia de train_numeric
train_numericoutliers=train_numeric.copy()
for column in train_numeric:
train_numericoutliers[column] = cap_floor_outliers(train_numericoutliers, column)
Outliers in LAT: 0 out of 82049 Outliers in LON: 0 out of 82049 Outliers in Precipitation: 16832 out of 82049 Outliers in LST: 164 out of 82049 Outliers in AAI: 3750 out of 82049 Outliers in CloudFraction: 9705 out of 82049 Outliers in NO2_strat: 2 out of 82049 Outliers in NO2_total: 8463 out of 82049 Outliers in NO2_trop: 7796 out of 82049 Outliers in TropopausePressure: 8902 out of 82049 Outliers in Year: 0 out of 82049 Outliers in Month: 0 out of 82049 Outliers in Day: 0 out of 82049
Busco mejor transformación para cada variable¶
Esto permite mejorar la relación entre las variables predictoras y el objetivo, aumentando la precisión
## Definción de función para encontrar mejor tranformación
def mejorTransf(vv, target, name=False, tipo='cramer', graf=False):
# Escalado de datos (evitar fallos de tamaño de float64 al hacer exp de número grande..cosas de python)
vv = pd.Series(scale(vv), name=vv.name)
# Traslación a valores positivos de la variable (sino falla log y las raíces!)
vv = vv + abs(min(vv)) + 0.0001
# Definimos y calculamos las transformaciones típicas
transf = pd.DataFrame({
vv.name + '_ident': vv,
vv.name + '_log': np.log(vv),
vv.name + '_exp': np.exp(vv),
vv.name + '_sqrt': np.sqrt(vv),
vv.name + '_sqr': np.square(vv),
vv.name + '_cuarta': vv**4,
vv.name + '_raiz4': vv**(1/4)
})
# Distinguimos caso cramer o caso correlación
if tipo == 'cramer':
# Aplicar la función cramers_v a cada transformación frente a la respuesta
tablaCramer = pd.DataFrame(transf.apply(lambda x: cramers_v(x, target)), columns=['VCramer'])
# Si queremos gráfico, muestra comparativa entre las posibilidades
if graf:
px.bar(tablaCramer, x=tablaCramer.VCramer, title='Relaciones frente a ' + target.name).update_yaxes(categoryorder="total ascending").show()
# Identificar mejor transformación
if not tablaCramer.empty:
best = tablaCramer.query('VCramer == VCramer.max()').index
if len(best) > 0:
ser = transf[best[0]].squeeze()
else:
ser = vv # Return original variable if no best transformation found
else:
ser = vv # Return original variable if tablaCramer is empty
if tipo == 'cor':
# Aplicar coeficiente de correlación a cada transformación frente a la respuesta
tablaCorr = pd.DataFrame(transf.apply(lambda x: np.corrcoef(x, target)[0, 1]), columns=['Corr'])
# Si queremos gráfico, muestra comparativa entre las posibilidades
if graf:
px.bar(tablaCorr, x=tablaCorr.Corr, title='Relaciones frente a ' + target.name).update_yaxes(categoryorder="total ascending").show()
# Identificar mejor transformación
if not tablaCorr.empty:
best = tablaCorr.query('Corr.abs() == Corr.abs().max()').index
if len(best) > 0:
ser = transf[best[0]].squeeze()
else:
ser = vv # Return original variable if no best transformation found
else:
ser = vv # Return original variable if tablaCorr is empty
# Aquí distingue si se devuelve la variable transformada o solamente el nombre de la transformación
if name:
return ser.name if 'ser' in locals() else vv.name
else:
return ser if 'ser' in locals() else vv
#Defino variable objetivo
varObj = train_numeric.GT_NO2
# Aplicar a las variables continuas la mejor transformación según correlacion frente a varObjCont
transf_cor = train_numericoutliers.apply(lambda x: mejorTransf(x,varObj, tipo='cor'))
# Pedir los nombres de las transformadas
transf_cor_names = train_numericoutliers.select_dtypes(include=np.number).apply(lambda x: mejorTransf(x,varObj,tipo='cor', name=True))
# Asignar nombres a las columnas de salida del proceso
transf_cor.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 82049 entries, 0 to 82048 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 LAT 82049 non-null float64 1 LON 82049 non-null float64 2 Precipitation 82049 non-null float64 3 LST 82049 non-null float64 4 AAI 82049 non-null float64 5 CloudFraction 82049 non-null float64 6 NO2_strat 82049 non-null float64 7 NO2_total 82049 non-null float64 8 NO2_trop 82049 non-null float64 9 TropopausePressure 82049 non-null float64 10 GT_NO2 82049 non-null float64 11 Year 82049 non-null float64 12 Month 82049 non-null float64 13 Day 82049 non-null float64 dtypes: float64(14) memory usage: 8.8 MB
La mejor transformación es la misma función. No se aplica ninguna transformación a las variables.¶
4. MODELADO DE DATOS¶
4.1 Normalizacion de datos.¶
#Normalizar data y target separados
x = train_numericoutliers.drop('GT_NO2', axis=1)
y = train_numericoutliers['GT_NO2']
# Normalizar toda la data para un mejor manejo.
scaler_train_x= MinMaxScaler()
scaler_train_y=MinMaxScaler()
#Normalizar features
X_scaled = scaler_train_x.fit_transform(x)
#Normalizar target
y_scaled = scaler_train_y.fit_transform(y.values.reshape(-1, 1))
# Fit and transform on the selected features
# Convert scaled data back to DataFrame
features_scaled = pd.DataFrame(X_scaled, columns=x.columns)
target_scaled=pd.DataFrame(y_scaled,columns=['GT_NO2'])
#Funcion para calcular metricas de modelos
def calculate_regression_metrics(y_real, y_pred):
# Calculate and print Mean Absolute Error
mae = mean_absolute_error(y_real, y_pred)
print('- Mean Absolute Error (MAE):', mae)
# Calculate and print Mean Squared Error
mse = mean_squared_error(y_real, y_pred)
print('- Mean Squared Error (MSE):', mse)
# Calculate and print Root Mean Squared Error
rmse = np.sqrt(mse)
print('- Root Mean Squared Error (RMSE):', rmse)
# Calculate and print R-squared
r2 = r2_score(y_real, y_pred)
print('- R-squared (R²):', r2)
4.2 Train/test¶
#Divido en train y test
X = features_scaled
y = target_scaled
X_train, X_test, y_train, y_test = train_test_split (X,
y,
test_size = 0.2,
random_state = 32)
4.3 PYCARET PARA DETERMINAR MEJOR MODELO¶
from pycaret.regression import setup, compare_models
#Set up PyCaret
model_setup = setup(data=X, target=y)
#Entrenar modelos
best_model = compare_models()
| Description | Value | |
|---|---|---|
| 0 | Session id | 5757 |
| 1 | Target | Day |
| 2 | Target type | Regression |
| 3 | Original data shape | (82049, 13) |
| 4 | Transformed data shape | (82049, 13) |
| 5 | Transformed train set shape | (57434, 13) |
| 6 | Transformed test set shape | (24615, 13) |
| 7 | Numeric features | 12 |
| 8 | Preprocess | True |
| 9 | Imputation type | simple |
| 10 | Numeric imputation | mean |
| 11 | Categorical imputation | mode |
| 12 | Fold Generator | KFold |
| 13 | Fold Number | 10 |
| 14 | CPU Jobs | -1 |
| 15 | Use GPU | False |
| 16 | Log Experiment | False |
| 17 | Experiment Name | reg-default-name |
| 18 | USI | b487 |
| Model | MAE | MSE | RMSE | R2 | RMSLE | MAPE | TT (Sec) | |
|---|---|---|---|---|---|---|---|---|
| et | Extra Trees Regressor | 0.0804 | 0.0211 | 0.1451 | 0.7556 | 0.1014 | 0.3820 | 1.4390 |
| rf | Random Forest Regressor | 0.0952 | 0.0237 | 0.1540 | 0.7248 | 0.1076 | 0.4559 | 5.3840 |
| xgboost | Extreme Gradient Boosting | 0.1447 | 0.0361 | 0.1901 | 0.5804 | 0.1329 | 0.6841 | 0.1010 |
| dt | Decision Tree Regressor | 0.0975 | 0.0445 | 0.2110 | 0.4830 | 0.1463 | 0.4346 | 0.1210 |
| knn | K Neighbors Regressor | 0.1472 | 0.0449 | 0.2118 | 0.4792 | 0.1471 | 0.6908 | 0.1060 |
| lightgbm | Light Gradient Boosting Machine | 0.1800 | 0.0483 | 0.2198 | 0.4394 | 0.1538 | 0.9058 | 0.3020 |
| gbr | Gradient Boosting Regressor | 0.2300 | 0.0726 | 0.2694 | 0.1577 | 0.1871 | 1.1798 | 2.0820 |
| ada | AdaBoost Regressor | 0.2501 | 0.0837 | 0.2894 | 0.0280 | 0.2005 | 1.2823 | 0.2520 |
| br | Bayesian Ridge | 0.2534 | 0.0857 | 0.2928 | 0.0052 | 0.2028 | 1.3031 | 0.0180 |
| ridge | Ridge Regression | 0.2534 | 0.0857 | 0.2928 | 0.0052 | 0.2028 | 1.3028 | 0.0160 |
| lr | Linear Regression | 0.2534 | 0.0857 | 0.2928 | 0.0052 | 0.2028 | 1.3028 | 0.3610 |
| huber | Huber Regressor | 0.2533 | 0.0858 | 0.2928 | 0.0045 | 0.2028 | 1.2991 | 0.1220 |
| omp | Orthogonal Matching Pursuit | 0.2536 | 0.0858 | 0.2929 | 0.0039 | 0.2029 | 1.3044 | 0.0150 |
| lasso | Lasso Regression | 0.2543 | 0.0862 | 0.2936 | -0.0005 | 0.2034 | 1.3146 | 0.0230 |
| en | Elastic Net | 0.2543 | 0.0862 | 0.2936 | -0.0005 | 0.2034 | 1.3146 | 0.0160 |
| llar | Lasso Least Angle Regression | 0.2543 | 0.0862 | 0.2936 | -0.0005 | 0.2034 | 1.3146 | 0.0130 |
| dummy | Dummy Regressor | 0.2543 | 0.0862 | 0.2936 | -0.0005 | 0.2034 | 1.3146 | 0.0170 |
| lar | Least Angle Regression | 0.2547 | 0.0874 | 0.2955 | -0.0145 | 0.2038 | 1.3067 | 0.0140 |
| par | Passive Aggressive Regressor | 0.3445 | 0.1797 | 0.4208 | -1.0827 | 0.2792 | 1.6766 | 0.0190 |
5. Modelos¶
5.1 XGB¶
# Inicializar modelo de XGBoost con parámetros específicos
model_xgb = xgb.XGBRegressor(
objective='reg:squarederror',
learning_rate=0.1,
max_depth=5,
n_estimators=100).fit(X_train, y_train)
# Realizar la predicción con los datos de prueba
XGB_pred = model_xgb.predict(X_test)
# Invertir la normalización de las predicciones para devolverlas a la escala original
XGB_pred = scaler_train_y.inverse_transform(XGB_pred.reshape(-1, 1))
# Remodelar y_test a 2D antes de invertir la normalización
y_test_original = scaler_train_y.inverse_transform(y_test.values.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, XGB_pred)
- Mean Absolute Error (MAE): 6.006018367691799 - Mean Squared Error (MSE): 68.56479333642116 - Root Mean Squared Error (RMSE): 8.280386062039689 - R-squared (R²): 0.75081991646561
5.2 Extra Trees Regressor¶
# Inicializar modelo
etr_model = ExtraTreesRegressor(
n_estimators=100,
random_state=42).fit(X_train, y_train)
# Realizar la predicción con los datos de prueba
etr_pred = etr_model.predict(X_test)
# Invertir la normalización de las predicciones para devolverlas a la escala original
etr_pred = scaler_train_y.inverse_transform(etr_pred.reshape(-1, 1))
# Remodelar y_test a 2D antes de invertir la normalización
y_test_original = scaler_train_y.inverse_transform(y_test.values.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, etr_pred)
- Mean Absolute Error (MAE): 5.405888005283127 - Mean Squared Error (MSE): 56.665957991521694 - Root Mean Squared Error (RMSE): 7.527679455949336 - R-squared (R²): 0.7940629956163938
5.4 Random Forest¶
# Inicializar modelo
model_rf = RandomForestRegressor(
n_estimators=100,
max_depth=5,
random_state=42).fit(X_train, y_train)
#Predicción
rand_forest_pred = model_rf.predict(X_test)
# Invertir la normalización de las predicciones para devolverlas a la escala original
rand_forest_pred = scaler_train_y.inverse_transform(rand_forest_pred.reshape(-1, 1))
# Remodelar y_test a 2D antes de invertir la normalización
y_test_original = scaler_train_y.inverse_transform(y_test.values.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, rand_forest_pred)
- Mean Absolute Error (MAE): 8.102475935667204 - Mean Squared Error (MSE): 120.31343488012884 - Root Mean Squared Error (RMSE): 10.968748099948728 - R-squared (R²): 0.5627535606117713
5.5 Decision Tree¶
# Inicializar modelo
model_tree = DecisionTreeRegressor(
max_depth=5).fit(X_train, y_train)
#Prediccion
dec_tree_pred = model_tree.predict(X_test)
# Invertir la normalización de las predicciones para devolverlas a la escala original
dec_tree_pred = scaler_train_y.inverse_transform(dec_tree_pred.reshape(-1, 1))
# Remodelar y_test a 2D antes de invertir la normalización
y_test_original = scaler_train_y.inverse_transform(y_test.values.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, dec_tree_pred)
- Mean Absolute Error (MAE): 8.242595368227718 - Mean Squared Error (MSE): 124.9022919556353 - Root Mean Squared Error (RMSE): 11.175969396684804 - R-squared (R²): 0.5460766082903139
6. Tecnicas para mejorar modelo¶
6.1 Extra Tree Regressor con Validación cruzada¶
Validación cruzada para evaluar el desempeño en diferentes subconjuntos de los datos, reduce el riesgo de overfitting
# Inicializar modelo
etr_model = ExtraTreesRegressor(
n_estimators=100,
random_state=42)
# Realizar validación cruzada
cv = KFold(n_splits=5, shuffle=True, random_state=42)
cv_scores = cross_val_score(etr_model, X_train, y_train, cv=cv, scoring='neg_mean_squared_error')
# Convertir las puntuaciones de MSE negativo a MSE positivo y luego a RMSE
cv_rmse_scores = np.sqrt(-cv_scores)
print(f"Puntuaciones de RMSE en Validación Cruzada: {cv_rmse_scores}")
print(f"RMSE Promedio: {cv_rmse_scores.mean()}")
# Ajustar el modelo en todo el conjunto de datos de entrenamiento después de la validación cruzada
etr_model.fit(X_train, y_train)
# Realizar predicciones en el conjunto de prueba
etr_pred = etr_model.predict(X_test)
# Invertir la normalización de las predicciones
etr_pred = scaler_train_y.inverse_transform(etr_pred.reshape(-1, 1))
# Invertir la normalización de los valores verdaderos del conjunto de prueba
y_test_original = scaler_train_y.inverse_transform(y_test)
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, etr_pred)
Puntuaciones de RMSE en Validación Cruzada: [0.09692637 0.09800576 0.09797212 0.097096 0.0965412 ] RMSE Promedio: 0.09730828891380468 - Mean Absolute Error (MAE): 5.405888005283127 - Mean Squared Error (MSE): 56.665957991521694 - Root Mean Squared Error (RMSE): 7.527679455949336 - R-squared (R²): 0.7940629956163938
6.1 Tunning de ETR¶
Busco hiperparametros que permitan mejorar ajuste del modelo
# Definir el modelo
etr = ExtraTreesRegressor(random_state=42)
# Definir los hyperparametros
param_grid = {
'n_estimators': [100, 200, 300],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4],
'bootstrap': [True, False]
}
# GridSearchCV
grid_search = GridSearchCV(estimator=etr, param_grid=param_grid, cv=5, n_jobs=-1, scoring='neg_mean_squared_error')
# Reshape y_train, y_test de ser necesario
y_train = np.ravel(y_train)
y_test = np.ravel(y_test)
# Fit GridSearchCV
grid_search.fit(X_train, y_train)
# Print mejores parametros y scroe
print(f"Best Parameters: {grid_search.best_params_}")
print(f"Best Score: {-grid_search.best_score_}")
Best Parameters: {'bootstrap': False, 'max_depth': 30, 'min_samples_leaf': 1, 'min_samples_split': 5, 'n_estimators': 300}
Best Score: 0.009302621048174812
#Agrego hiperparametros al modelo
#Inicializar modelo
etr_tunned = ExtraTreesRegressor(
n_estimators=300,
bootstrap=False,
max_depth= 30,
min_samples_leaf=1,
min_samples_split=5,
random_state=42).fit(X_train, y_train)
# Realizar validación cruzada
cv = KFold(n_splits=5, shuffle=True, random_state=42)
cv_scores = cross_val_score(etr_tunned, X_train, y_train, cv=cv, scoring='neg_mean_squared_error')
# Convertir las puntuaciones de MSE negativo a MSE positivo y luego a RMSE
cv_rmse_scores = np.sqrt(-cv_scores)
print(f"Puntuaciones de RMSE en Validación Cruzada (normalizado): {cv_rmse_scores}")
print(f"RMSE Promedio (Normalizado): {cv_rmse_scores.mean()}")
# Ajustar el modelo en todo el conjunto de datos de entrenamiento después de la validación cruzada
etr_tunned.fit(X_train, y_train)
# Realizar predicciones en el conjunto de prueba
etr_pred = etr_tunned.predict(X_test)
# Invertir la normalización de las predicciones
etr_pred = scaler_train_y.inverse_transform(etr_pred.reshape(-1, 1))
# Invertir la normalización de los valores verdaderos del conjunto de prueba
y_test_original = scaler_train_y.inverse_transform(y_test.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, etr_pred)
Puntuaciones de RMSE en Validación Cruzada (normalizado): [0.09587721 0.0972971 0.09747166 0.09622014 0.09565425] RMSE Promedio (Normalizado): 0.0965040739601254 - Mean Absolute Error (MAE): 5.369666311247146 - Mean Squared Error (MSE): 55.51723532967755 - Root Mean Squared Error (RMSE): 7.4509888826703765 - R-squared (R²): 0.7982377155405349
6.4 Verifico importancia de variables de ETR¶
# Obtener importancia
importances = etr_tunned.feature_importances_
# Crear DataFrame para visualizacion
import pandas as pd
importances_df = pd.DataFrame({
'Feature': X_train.columns,
'Importance': importances
}).sort_values(by='Importance', ascending=False)
# Print importancia
print(importances_df)
# Plot
plt.figure(figsize=(10, 6))
plt.barh(importances_df['Feature'], importances_df['Importance'], color='skyblue')
plt.xlabel('Importance')
plt.title('Feature Importance from Extra Trees Regressor Model')
plt.gca().invert_yaxis()
plt.show()
Feature Importance 8 NO2_trop 0.222963 7 NO2_total 0.152789 0 LAT 0.110895 11 Month 0.106095 6 NO2_strat 0.097798 1 LON 0.090353 3 LST 0.047630 12 Day 0.044465 10 Year 0.032420 5 CloudFraction 0.030928 9 TropopausePressure 0.021844 4 AAI 0.021588 2 Precipitation 0.020232
De los plots se observa como LST, AAI, CloudFraction y Day tienen uy poca influencia en la variable objetivo. Un cambio en estos parametros no impacta en la dependencia
#Partial Dependence Plots
# Especificar los índices de las características que deseas visualizar
features = list(range(X_train.shape[1])) # Índices de todas las características en X_train
# Crear Partial Dependence Plots para todas las características
fig, ax = plt.subplots(figsize=(15, 10))
display = PartialDependenceDisplay.from_estimator(etr_tunned, X_train, features, grid_resolution=50, ax=ax)
# Personalizar el gráfico
plt.suptitle('Partial Dependence Plots', fontsize=16)
plt.subplots_adjust(hspace=0.5, top=0.9) # Ajustar para que el título no se superponga
plt.show()
#Inspeccionar resultados basados en variables presentes
def calculate_regression_metrics_modified(y_true, y_pred):
mse = mean_squared_error(y_true, y_pred)
print(f"MSE: {mse}")
return mse
# Definir las variables a probar
variables_to_check = ['Precipitation', 'LST', 'AAI','CloudFraction','TropopausePressure','Year','Day','NO2_trop','NO2_total'] # reemplaza con las variables que quieras probar
# Crear combinaciones de variables para eliminar
combinations = sum([list(itertools.combinations(variables_to_check, i)) for i in range(len(variables_to_check) + 1)], [])
# Inicializar variables para rastrear el mejor rendimiento
best_mse = float("inf")
best_combination = None
# Iterar sobre cada combinación de variables para eliminar
for combination in combinations:
print(f"Evaluando combinación: {combination}")
X_with_importance = features_scaled.drop(columns=list(combination))
X_train_imp, X_test_imp, y_train, y_test = train_test_split(X_with_importance, y, test_size=0.2, random_state=32)
# Inicializo modelo
etr_with_importance = ExtraTreesRegressor(
n_estimators=300,
bootstrap=False,
max_depth= None,
min_samples_leaf=1,
min_samples_split=5,
random_state=42).fit(X_train_imp, y_train)
#Prediccion
etr_pred = etr_with_importance.predict(X_test_imp)
# Métricas
mse = calculate_regression_metrics_modified(y_test, etr_pred)
# Actualizar la mejor combinación si se encuentra un mejor MSE
if mse < best_mse:
best_mse = mse
best_combination = combination
print(f"\nLa mejor combinación de variables para eliminar es: {best_combination} con un MSE de: {best_mse}")
Evaluando combinación: ()
MSE: 0.001710798560239363
Evaluando combinación: ('Precipitation',)
MSE: 0.0017163701252516214
Evaluando combinación: ('LST',)
MSE: 0.00169427902656036
Evaluando combinación: ('AAI',)
MSE: 0.0017041602865189621
Evaluando combinación: ('CloudFraction',)
MSE: 0.0016911035290114087
Evaluando combinación: ('TropopausePressure',)
MSE: 0.0017178149567215145
Evaluando combinación: ('Year',)
MSE: 0.00190813277376611
Evaluando combinación: ('Day',)
MSE: 0.001971594774190272
Evaluando combinación: ('NO2_trop',)
MSE: 0.0016713820819565896
Evaluando combinación: ('NO2_total',)
MSE: 0.0016683676796807898
Evaluando combinación: ('Precipitation', 'LST')
MSE: 0.001685760062280268
Evaluando combinación: ('Precipitation', 'AAI')
MSE: 0.001695299830411942
Evaluando combinación: ('Precipitation', 'CloudFraction')
MSE: 0.001673084926773359
Evaluando combinación: ('Precipitation', 'TropopausePressure')
MSE: 0.0017176562993297978
Evaluando combinación: ('Precipitation', 'Year')
MSE: 0.0019961374862667693
Evaluando combinación: ('Precipitation', 'Day')
MSE: 0.001993196825393257
Evaluando combinación: ('Precipitation', 'NO2_trop')
MSE: 0.0016571342476561126
Evaluando combinación: ('Precipitation', 'NO2_total')
MSE: 0.0016594914248873264
Evaluando combinación: ('LST', 'AAI')
MSE: 0.0016798812284715375
Evaluando combinación: ('LST', 'CloudFraction')
MSE: 0.0016686771482349592
Evaluando combinación: ('LST', 'TropopausePressure')
MSE: 0.0017002364912220278
Evaluando combinación: ('LST', 'Year')
MSE: 0.0019070362244934013
Evaluando combinación: ('LST', 'Day')
MSE: 0.0019587917154210896
Evaluando combinación: ('LST', 'NO2_trop')
MSE: 0.0016458519609282626
Evaluando combinación: ('LST', 'NO2_total')
MSE: 0.001646656585443527
Evaluando combinación: ('AAI', 'CloudFraction')
MSE: 0.001668689779031268
Evaluando combinación: ('AAI', 'TropopausePressure')
MSE: 0.0017169255988716626
Evaluando combinación: ('AAI', 'Year')
MSE: 0.0019284406638905743
Evaluando combinación: ('AAI', 'Day')
MSE: 0.0019586454393884538
Evaluando combinación: ('AAI', 'NO2_trop')
MSE: 0.0016478628574041288
Evaluando combinación: ('AAI', 'NO2_total')
MSE: 0.001643350012580823
Evaluando combinación: ('CloudFraction', 'TropopausePressure')
MSE: 0.001689910761842441
Evaluando combinación: ('CloudFraction', 'Year')
MSE: 0.0018960193328693253
Evaluando combinación: ('CloudFraction', 'Day')
MSE: 0.0019466779015680049
Evaluando combinación: ('CloudFraction', 'NO2_trop')
MSE: 0.0016280940502903483
Evaluando combinación: ('CloudFraction', 'NO2_total')
MSE: 0.0016345233529382682
Evaluando combinación: ('TropopausePressure', 'Year')
MSE: 0.0019333510300027356
Evaluando combinación: ('TropopausePressure', 'Day')
MSE: 0.00198585463543082
Evaluando combinación: ('TropopausePressure', 'NO2_trop')
MSE: 0.0016643006532933906
Evaluando combinación: ('TropopausePressure', 'NO2_total')
MSE: 0.0016707098861935728
Evaluando combinación: ('Year', 'Day')
MSE: 0.0021311015749362104
Evaluando combinación: ('Year', 'NO2_trop')
MSE: 0.0018660310018541095
Evaluando combinación: ('Year', 'NO2_total')
MSE: 0.0018627630047927568
Evaluando combinación: ('Day', 'NO2_trop')
MSE: 0.001916802892863608
Evaluando combinación: ('Day', 'NO2_total')
MSE: 0.0019230032923553606
Evaluando combinación: ('NO2_trop', 'NO2_total')
MSE: 0.0014341410921824302
Evaluando combinación: ('Precipitation', 'LST', 'AAI')
MSE: 0.0016774217678798223
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction')
MSE: 0.0016581479996768118
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure')
MSE: 0.0017059279097116954
Evaluando combinación: ('Precipitation', 'LST', 'Year')
MSE: 0.0019908894744881294
Evaluando combinación: ('Precipitation', 'LST', 'Day')
MSE: 0.0019821889195753744
Evaluando combinación: ('Precipitation', 'LST', 'NO2_trop')
MSE: 0.0016335695854424424
Evaluando combinación: ('Precipitation', 'LST', 'NO2_total')
MSE: 0.0016297608734230178
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction')
MSE: 0.0016705356450974942
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure')
MSE: 0.0017108773487211953
Evaluando combinación: ('Precipitation', 'AAI', 'Year')
MSE: 0.002021406271009907
Evaluando combinación: ('Precipitation', 'AAI', 'Day')
MSE: 0.0019882731966712214
Evaluando combinación: ('Precipitation', 'AAI', 'NO2_trop')
MSE: 0.0016563796927678758
Evaluando combinación: ('Precipitation', 'AAI', 'NO2_total')
MSE: 0.001644444127930593
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure')
MSE: 0.0016905623523868162
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Year')
MSE: 0.0019857274261843682
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Day')
MSE: 0.001981892041471411
Evaluando combinación: ('Precipitation', 'CloudFraction', 'NO2_trop')
MSE: 0.0016320200199688925
Evaluando combinación: ('Precipitation', 'CloudFraction', 'NO2_total')
MSE: 0.0016335472104635528
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Year')
MSE: 0.002016326837066345
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Day')
MSE: 0.0020169982570954234
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016671037050509214
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'NO2_total')
MSE: 0.0016619306876630635
Evaluando combinación: ('Precipitation', 'Year', 'Day')
MSE: 0.002155501810840399
Evaluando combinación: ('Precipitation', 'Year', 'NO2_trop')
MSE: 0.0019525121948156905
Evaluando combinación: ('Precipitation', 'Year', 'NO2_total')
MSE: 0.0019494787185557125
Evaluando combinación: ('Precipitation', 'Day', 'NO2_trop')
MSE: 0.0019557733007746422
Evaluando combinación: ('Precipitation', 'Day', 'NO2_total')
MSE: 0.0019508659626061738
Evaluando combinación: ('Precipitation', 'NO2_trop', 'NO2_total')
MSE: 0.0014340852419803386
Evaluando combinación: ('LST', 'AAI', 'CloudFraction')
MSE: 0.001658701251828903
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure')
MSE: 0.0016987358239965963
Evaluando combinación: ('LST', 'AAI', 'Year')
MSE: 0.0019236970567830679
Evaluando combinación: ('LST', 'AAI', 'Day')
MSE: 0.0019559941768381777
Evaluando combinación: ('LST', 'AAI', 'NO2_trop')
MSE: 0.0016303244357181326
Evaluando combinación: ('LST', 'AAI', 'NO2_total')
MSE: 0.0016302054425095657
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure')
MSE: 0.0016850523248107445
Evaluando combinación: ('LST', 'CloudFraction', 'Year')
MSE: 0.0019015371089188698
Evaluando combinación: ('LST', 'CloudFraction', 'Day')
MSE: 0.0019484914861555422
Evaluando combinación: ('LST', 'CloudFraction', 'NO2_trop')
MSE: 0.0016172201284389291
Evaluando combinación: ('LST', 'CloudFraction', 'NO2_total')
MSE: 0.0016192668529077013
Evaluando combinación: ('LST', 'TropopausePressure', 'Year')
MSE: 0.0019319083708758478
Evaluando combinación: ('LST', 'TropopausePressure', 'Day')
MSE: 0.0019902229773614078
Evaluando combinación: ('LST', 'TropopausePressure', 'NO2_trop')
MSE: 0.001649289693836734
Evaluando combinación: ('LST', 'TropopausePressure', 'NO2_total')
MSE: 0.0016513681016709144
Evaluando combinación: ('LST', 'Year', 'Day')
MSE: 0.0021309915059046255
Evaluando combinación: ('LST', 'Year', 'NO2_trop')
MSE: 0.0018508819471542237
Evaluando combinación: ('LST', 'Year', 'NO2_total')
MSE: 0.0018527322084994087
Evaluando combinación: ('LST', 'Day', 'NO2_trop')
MSE: 0.00190877300977146
Evaluando combinación: ('LST', 'Day', 'NO2_total')
MSE: 0.0019054647305834255
Evaluando combinación: ('LST', 'NO2_trop', 'NO2_total')
MSE: 0.0014164049986496213
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure')
MSE: 0.0016791803546092393
Evaluando combinación: ('AAI', 'CloudFraction', 'Year')
MSE: 0.0019216091570257237
Evaluando combinación: ('AAI', 'CloudFraction', 'Day')
MSE: 0.0019468641062081657
Evaluando combinación: ('AAI', 'CloudFraction', 'NO2_trop')
MSE: 0.0016280720320465852
Evaluando combinación: ('AAI', 'CloudFraction', 'NO2_total')
MSE: 0.0016208334473780666
Evaluando combinación: ('AAI', 'TropopausePressure', 'Year')
MSE: 0.001959308343377483
Evaluando combinación: ('AAI', 'TropopausePressure', 'Day')
MSE: 0.0019889104627444135
Evaluando combinación: ('AAI', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016592627499550483
Evaluando combinación: ('AAI', 'TropopausePressure', 'NO2_total')
MSE: 0.0016565919573053455
Evaluando combinación: ('AAI', 'Year', 'Day')
MSE: 0.0021567255661271347
Evaluando combinación: ('AAI', 'Year', 'NO2_trop')
MSE: 0.001880412944529625
Evaluando combinación: ('AAI', 'Year', 'NO2_total')
MSE: 0.0018807162017466027
Evaluando combinación: ('AAI', 'Day', 'NO2_trop')
MSE: 0.0019144059008066145
Evaluando combinación: ('AAI', 'Day', 'NO2_total')
MSE: 0.0019113311018306388
Evaluando combinación: ('AAI', 'NO2_trop', 'NO2_total')
MSE: 0.0014269744359608051
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Year')
MSE: 0.001928968429791531
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Day')
MSE: 0.0019750925597601266
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'NO2_trop')
MSE: 0.001644625038015871
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'NO2_total')
MSE: 0.0016417552078280813
Evaluando combinación: ('CloudFraction', 'Year', 'Day')
MSE: 0.0021331228678018125
Evaluando combinación: ('CloudFraction', 'Year', 'NO2_trop')
MSE: 0.0018555449850407844
Evaluando combinación: ('CloudFraction', 'Year', 'NO2_total')
MSE: 0.0018552749764311639
Evaluando combinación: ('CloudFraction', 'Day', 'NO2_trop')
MSE: 0.001907397659895152
Evaluando combinación: ('CloudFraction', 'Day', 'NO2_total')
MSE: 0.0019072666928727816
Evaluando combinación: ('CloudFraction', 'NO2_trop', 'NO2_total')
MSE: 0.00142839654586229
Evaluando combinación: ('TropopausePressure', 'Year', 'Day')
MSE: 0.0021665151302875728
Evaluando combinación: ('TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0018787437925716494
Evaluando combinación: ('TropopausePressure', 'Year', 'NO2_total')
MSE: 0.00188587153580073
Evaluando combinación: ('TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019467845792231664
Evaluando combinación: ('TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019349650953094262
Evaluando combinación: ('TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014833058072294047
Evaluando combinación: ('Year', 'Day', 'NO2_trop')
MSE: 0.002088403840083471
Evaluando combinación: ('Year', 'Day', 'NO2_total')
MSE: 0.0020857234585374093
Evaluando combinación: ('Year', 'NO2_trop', 'NO2_total')
MSE: 0.001746402668921263
Evaluando combinación: ('Day', 'NO2_trop', 'NO2_total')
MSE: 0.0018187464763950874
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction')
MSE: 0.0016578581565275525
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure')
MSE: 0.001699072392393779
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Year')
MSE: 0.0020098554195216133
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Day')
MSE: 0.0019869534644312127
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'NO2_trop')
MSE: 0.0016262566251973585
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'NO2_total')
MSE: 0.0016259227615059379
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure')
MSE: 0.0016885298238608379
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Year')
MSE: 0.0019902250902983165
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Day')
MSE: 0.0019810763393822393
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'NO2_trop')
MSE: 0.0016103439393293324
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'NO2_total')
MSE: 0.0016151445998312326
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Year')
MSE: 0.0020153191732156534
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Day')
MSE: 0.0020210840526656785
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016493777682153204
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'NO2_total')
MSE: 0.0016530775689933852
Evaluando combinación: ('Precipitation', 'LST', 'Year', 'Day')
MSE: 0.0021562651549780487
Evaluando combinación: ('Precipitation', 'LST', 'Year', 'NO2_trop')
MSE: 0.001944065625555352
Evaluando combinación: ('Precipitation', 'LST', 'Year', 'NO2_total')
MSE: 0.0019375218837193661
Evaluando combinación: ('Precipitation', 'LST', 'Day', 'NO2_trop')
MSE: 0.001938585238351406
Evaluando combinación: ('Precipitation', 'LST', 'Day', 'NO2_total')
MSE: 0.001932395516878413
Evaluando combinación: ('Precipitation', 'LST', 'NO2_trop', 'NO2_total')
MSE: 0.0014025207196999164
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure')
MSE: 0.0016825493488793939
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Year')
MSE: 0.0020096442879794945
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Day')
MSE: 0.0019816586216283762
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'NO2_trop')
MSE: 0.001619902388194587
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'NO2_total')
MSE: 0.001616850602120737
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Year')
MSE: 0.002044745782263613
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Day')
MSE: 0.0020260294195784266
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016614645396623307
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'NO2_total')
MSE: 0.0016563775532497636
Evaluando combinación: ('Precipitation', 'AAI', 'Year', 'Day')
MSE: 0.0021843926631814874
Evaluando combinación: ('Precipitation', 'AAI', 'Year', 'NO2_trop')
MSE: 0.001967976946836933
Evaluando combinación: ('Precipitation', 'AAI', 'Year', 'NO2_total')
MSE: 0.0019678250161989028
Evaluando combinación: ('Precipitation', 'AAI', 'Day', 'NO2_trop')
MSE: 0.0019427711119303032
Evaluando combinación: ('Precipitation', 'AAI', 'Day', 'NO2_total')
MSE: 0.0019393705618200813
Evaluando combinación: ('Precipitation', 'AAI', 'NO2_trop', 'NO2_total')
MSE: 0.0014201093892571494
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Year')
MSE: 0.0020177691122563717
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Day')
MSE: 0.002014008042878393
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016410493960488715
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'NO2_total')
MSE: 0.0016453947714918653
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Year', 'Day')
MSE: 0.0021652617565822343
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Year', 'NO2_trop')
MSE: 0.0019444554358379012
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Year', 'NO2_total')
MSE: 0.0019430278898474806
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Day', 'NO2_trop')
MSE: 0.00193574081307976
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Day', 'NO2_total')
MSE: 0.0019340092209191287
Evaluando combinación: ('Precipitation', 'CloudFraction', 'NO2_trop', 'NO2_total')
MSE: 0.0014256320244470386
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Year', 'Day')
MSE: 0.002193715072952866
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.001975973463342417
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0019718407642342964
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019647543933396473
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019753712103784864
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014767057709128783
Evaluando combinación: ('Precipitation', 'Year', 'Day', 'NO2_trop')
MSE: 0.002116576268010374
Evaluando combinación: ('Precipitation', 'Year', 'Day', 'NO2_total')
MSE: 0.002113338971888095
Evaluando combinación: ('Precipitation', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0018363164204041492
Evaluando combinación: ('Precipitation', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.001857197598367141
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure')
MSE: 0.001677911877410428
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Year')
MSE: 0.0019279932706548234
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Day')
MSE: 0.0019611522820538758
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'NO2_trop')
MSE: 0.001608226839957349
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'NO2_total')
MSE: 0.0016032080845592284
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Year')
MSE: 0.0019666398045482592
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Day')
MSE: 0.0019977532627918596
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016473177668914762
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'NO2_total')
MSE: 0.0016279517464306789
Evaluando combinación: ('LST', 'AAI', 'Year', 'Day')
MSE: 0.0021666755757616995
Evaluando combinación: ('LST', 'AAI', 'Year', 'NO2_trop')
MSE: 0.0018702367899247898
Evaluando combinación: ('LST', 'AAI', 'Year', 'NO2_total')
MSE: 0.0018724246516043732
Evaluando combinación: ('LST', 'AAI', 'Day', 'NO2_trop')
MSE: 0.0019099061172959044
Evaluando combinación: ('LST', 'AAI', 'Day', 'NO2_total')
MSE: 0.0018908315541525688
Evaluando combinación: ('LST', 'AAI', 'NO2_trop', 'NO2_total')
MSE: 0.0014026510254765727
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Year')
MSE: 0.0019635905760817043
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Day')
MSE: 0.0020047490657225343
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016227140653869475
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'NO2_total')
MSE: 0.0016322614694910232
Evaluando combinación: ('LST', 'CloudFraction', 'Year', 'Day')
MSE: 0.002163590236685033
Evaluando combinación: ('LST', 'CloudFraction', 'Year', 'NO2_trop')
MSE: 0.001853772145629453
Evaluando combinación: ('LST', 'CloudFraction', 'Year', 'NO2_total')
MSE: 0.00185369620839419
Evaluando combinación: ('LST', 'CloudFraction', 'Day', 'NO2_trop')
MSE: 0.0019041156134551452
Evaluando combinación: ('LST', 'CloudFraction', 'Day', 'NO2_total')
MSE: 0.0019054100424904252
Evaluando combinación: ('LST', 'CloudFraction', 'NO2_trop', 'NO2_total')
MSE: 0.0014214346449482433
Evaluando combinación: ('LST', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0021785010606895725
Evaluando combinación: ('LST', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0018835985545464983
Evaluando combinación: ('LST', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0018809921285779824
Evaluando combinación: ('LST', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019439722389545464
Evaluando combinación: ('LST', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.001937198859843296
Evaluando combinación: ('LST', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014618248418168797
Evaluando combinación: ('LST', 'Year', 'Day', 'NO2_trop')
MSE: 0.0020822531945213336
Evaluando combinación: ('LST', 'Year', 'Day', 'NO2_total')
MSE: 0.0020835271709134574
Evaluando combinación: ('LST', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0017383996659046073
Evaluando combinación: ('LST', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0018443617468154945
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Year')
MSE: 0.0019661771090957346
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Day')
MSE: 0.001997741795917948
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016283457442262399
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'NO2_total')
MSE: 0.0016305776166651471
Evaluando combinación: ('AAI', 'CloudFraction', 'Year', 'Day')
MSE: 0.002185015508242003
Evaluando combinación: ('AAI', 'CloudFraction', 'Year', 'NO2_trop')
MSE: 0.0018705400048618726
Evaluando combinación: ('AAI', 'CloudFraction', 'Year', 'NO2_total')
MSE: 0.0018724944214110974
Evaluando combinación: ('AAI', 'CloudFraction', 'Day', 'NO2_trop')
MSE: 0.0018980320289980958
Evaluando combinación: ('AAI', 'CloudFraction', 'Day', 'NO2_total')
MSE: 0.0018984845743017001
Evaluando combinación: ('AAI', 'CloudFraction', 'NO2_trop', 'NO2_total')
MSE: 0.001416083000279208
Evaluando combinación: ('AAI', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0022179603785548977
Evaluando combinación: ('AAI', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0019149530902474042
Evaluando combinación: ('AAI', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0019159878928611024
Evaluando combinación: ('AAI', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019411567053825086
Evaluando combinación: ('AAI', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019331074602075293
Evaluando combinación: ('AAI', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.001486504235808222
Evaluando combinación: ('AAI', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021213660941292348
Evaluando combinación: ('AAI', 'Year', 'Day', 'NO2_total')
MSE: 0.0021161933653106235
Evaluando combinación: ('AAI', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0017896833037798785
Evaluando combinación: ('AAI', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0018415930926167692
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0021929703541320312
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0018819795122906474
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0018882146571345176
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019340021553984734
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019351696090219232
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014819689141620455
Evaluando combinación: ('CloudFraction', 'Year', 'Day', 'NO2_trop')
MSE: 0.0020962602349888534
Evaluando combinación: ('CloudFraction', 'Year', 'Day', 'NO2_total')
MSE: 0.0020989626560005974
Evaluando combinación: ('CloudFraction', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0017493037903224405
Evaluando combinación: ('CloudFraction', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0018558101640476833
Evaluando combinación: ('TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021260983729956408
Evaluando combinación: ('TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002122787161231858
Evaluando combinación: ('TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.001879893712961147
Evaluando combinación: ('TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.001958008206961842
Evaluando combinación: ('Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002144301111206815
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure')
MSE: 0.0016853803131804336
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Year')
MSE: 0.002021498892219962
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Day')
MSE: 0.0020028627605601667
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'NO2_trop')
MSE: 0.0016002312635334034
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'NO2_total')
MSE: 0.0016012795046756495
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Year')
MSE: 0.002059636550157889
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Day')
MSE: 0.002037860605879122
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016340075493791516
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'NO2_total')
MSE: 0.0016328996356652274
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Year', 'Day')
MSE: 0.0022040111938300194
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Year', 'NO2_trop')
MSE: 0.001959487803096992
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Year', 'NO2_total')
MSE: 0.001961872674129234
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Day', 'NO2_trop')
MSE: 0.0019336921163849966
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Day', 'NO2_total')
MSE: 0.0019282448591743289
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'NO2_trop', 'NO2_total')
MSE: 0.0013923663945746177
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Year')
MSE: 0.002053159610039536
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Day')
MSE: 0.002058870136119041
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'NO2_trop')
MSE: 0.001626456838617161
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'NO2_total')
MSE: 0.0016392166432975235
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Year', 'Day')
MSE: 0.002188555355724715
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Year', 'NO2_trop')
MSE: 0.0019375627885662367
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Year', 'NO2_total')
MSE: 0.0019470393398948749
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Day', 'NO2_trop')
MSE: 0.0019382618870241878
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Day', 'NO2_total')
MSE: 0.001940023744735716
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'NO2_trop', 'NO2_total')
MSE: 0.001418066342700955
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0022134516532029483
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0019715814388360595
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.001968779008235627
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.001975711777957038
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019683876690524335
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014552608931472056
Evaluando combinación: ('Precipitation', 'LST', 'Year', 'Day', 'NO2_trop')
MSE: 0.002114330443768081
Evaluando combinación: ('Precipitation', 'LST', 'Year', 'Day', 'NO2_total')
MSE: 0.002111396061045338
Evaluando combinación: ('Precipitation', 'LST', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0018330043120487031
Evaluando combinación: ('Precipitation', 'LST', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0018798866580494544
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year')
MSE: 0.0020570785470429044
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day')
MSE: 0.0020396218948495063
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_trop')
MSE: 0.001627739791144661
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_total')
MSE: 0.0016241691749959814
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Year', 'Day')
MSE: 0.0022141799468202387
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Year', 'NO2_trop')
MSE: 0.001965652749551323
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Year', 'NO2_total')
MSE: 0.0019644421926815142
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Day', 'NO2_trop')
MSE: 0.0019410541891097214
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Day', 'NO2_total')
MSE: 0.0019296014486542788
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'NO2_trop', 'NO2_total')
MSE: 0.0014123711334936512
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Year', 'Day')
MSE: 0.002249912451266552
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.002003246737601967
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.002001738399961375
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019787375905036086
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019732341768026796
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014712267612481224
Evaluando combinación: ('Precipitation', 'AAI', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021503568932251553
Evaluando combinación: ('Precipitation', 'AAI', 'Year', 'Day', 'NO2_total')
MSE: 0.002150817880394033
Evaluando combinación: ('Precipitation', 'AAI', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0018804536810445812
Evaluando combinación: ('Precipitation', 'AAI', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0018791152141058207
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Year', 'Day')
MSE: 0.002224173802816036
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0019719581568148855
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0019759761804930254
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.001969546272284074
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019749686880118564
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.001474215051550131
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021244720966502413
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Year', 'Day', 'NO2_total')
MSE: 0.0021272859062289057
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0018365342781343941
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.00189463626111022
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021518603470968164
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.0021526069053017733
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.00197783896236574
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0020016308652248383
Evaluando combinación: ('Precipitation', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0021831873302767995
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year')
MSE: 0.0020162288011261946
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day')
MSE: 0.002046707028878472
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_trop')
MSE: 0.001619978200629857
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_total')
MSE: 0.0016319276498883888
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Year', 'Day')
MSE: 0.0022317820097519773
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Year', 'NO2_trop')
MSE: 0.001878000576048871
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Year', 'NO2_total')
MSE: 0.0018794871172044872
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Day', 'NO2_trop')
MSE: 0.0019183829251737373
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Day', 'NO2_total')
MSE: 0.0019099411152204591
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'NO2_trop', 'NO2_total')
MSE: 0.0014116170495337562
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0022522464488616382
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0019206226918112798
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0019157305553981422
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019515472755116474
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019459457788259364
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014566196965922736
Evaluando combinación: ('LST', 'AAI', 'Year', 'Day', 'NO2_trop')
MSE: 0.002134326675267437
Evaluando combinación: ('LST', 'AAI', 'Year', 'Day', 'NO2_total')
MSE: 0.002129484776677291
Evaluando combinación: ('LST', 'AAI', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0017956621524994143
Evaluando combinación: ('LST', 'AAI', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0018896155196842755
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0022611195548236
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0019108030466377535
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0019133162947726032
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019575841399392855
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019696697991575746
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014866346985388935
Evaluando combinación: ('LST', 'CloudFraction', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021277024359627975
Evaluando combinación: ('LST', 'CloudFraction', 'Year', 'Day', 'NO2_total')
MSE: 0.0021286458773616557
Evaluando combinación: ('LST', 'CloudFraction', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0017644949701634345
Evaluando combinación: ('LST', 'CloudFraction', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0019169823491365114
Evaluando combinación: ('LST', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021391407081467733
Evaluando combinación: ('LST', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.0021408026440085767
Evaluando combinación: ('LST', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.001904833455433891
Evaluando combinación: ('LST', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0020404144048790283
Evaluando combinación: ('LST', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002193819370973131
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0022728979996925777
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0019264157724035056
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.001921413408335566
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019511762795189124
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019438366989802266
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014773754575203519
Evaluando combinación: ('AAI', 'CloudFraction', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021491793695021387
Evaluando combinación: ('AAI', 'CloudFraction', 'Year', 'Day', 'NO2_total')
MSE: 0.002143909072592056
Evaluando combinación: ('AAI', 'CloudFraction', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0018041027687276266
Evaluando combinación: ('AAI', 'CloudFraction', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0019105304268829408
Evaluando combinación: ('AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.002185052804937371
Evaluando combinación: ('AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002180713107636898
Evaluando combinación: ('AAI', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.001986167326327343
Evaluando combinación: ('AAI', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0020507697983858
Evaluando combinación: ('AAI', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0022781284834632147
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021604096553529194
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.0021552952799309922
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.001906182598998839
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002059747671143158
Evaluando combinación: ('CloudFraction', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0022182027929012562
Evaluando combinación: ('TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002339847237661802
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year')
MSE: 0.002117224335513537
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day')
MSE: 0.002105903069704193
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_trop')
MSE: 0.0016335581910761894
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_total')
MSE: 0.0016348134129215734
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Year', 'Day')
MSE: 0.0022640997810811432
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Year', 'NO2_trop')
MSE: 0.001971516533357253
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Year', 'NO2_total')
MSE: 0.001977892634151015
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Day', 'NO2_trop')
MSE: 0.0019579062983247023
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Day', 'NO2_total')
MSE: 0.0019571545105102426
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'NO2_trop', 'NO2_total')
MSE: 0.001412698430558258
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0022906237437942787
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.00201274912052411
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0020105792936895425
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019846065570595264
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.001985902549945493
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.001458053981958851
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021633391997144674
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Year', 'Day', 'NO2_total')
MSE: 0.0021616544477930624
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.001890496179491313
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0019362189753220006
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Year', 'Day')
MSE: 0.002298274089917017
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0020056156637633903
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0020086366118839544
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.002011554514495829
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0020217471690213364
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014809267253999316
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Year', 'Day', 'NO2_trop')
MSE: 0.002150949724163053
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Year', 'Day', 'NO2_total')
MSE: 0.0021526401207856843
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.001848907730877463
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.001959523081919085
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.0021714301365511777
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.0021664258457373725
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0020020597484748724
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0020759675815981778
Evaluando combinación: ('Precipitation', 'LST', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0022159052907270425
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0023059743182582667
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.002021676023648352
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.00201807519419177
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.0019992900343097997
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.0019917939520082886
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014741744838877202
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_trop')
MSE: 0.002179573582678365
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_total')
MSE: 0.00217704603998694
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0018982867927034616
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0019411434063225888
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.002211636583192266
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.0022112549752781444
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.002079560879785456
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0020855947979011246
Evaluando combinación: ('Precipitation', 'AAI', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0023127612072235864
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.002183787363558315
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002187834203122528
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.002002680508790575
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0020985230038860023
Evaluando combinación: ('Precipitation', 'CloudFraction', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0022503082692208374
Evaluando combinación: ('Precipitation', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.00238915655041056
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0023881102303762707
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.0019716460724805776
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.001976208684201279
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.002013953552769983
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.002016256371282118
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.0014908453432382924
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_trop')
MSE: 0.002203508118198926
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_total')
MSE: 0.002201700987127988
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.00183196327731813
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0020236453515656686
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.002220625384748205
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002217466369548641
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0020348169616824113
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0021825674564278155
Evaluando combinación: ('LST', 'AAI', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002356938875048201
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.002233497884145978
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.0022311436756772248
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0019689215002584633
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002232326837309073
Evaluando combinación: ('LST', 'CloudFraction', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0023080678102797097
Evaluando combinación: ('LST', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0024466258432733904
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.002242509850070494
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002241381125865979
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.0020306593814871645
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0021961437841416173
Evaluando combinación: ('AAI', 'CloudFraction', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0023826797001407756
Evaluando combinación: ('AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0025590852031784185
Evaluando combinación: ('CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0024669521017142717
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day')
MSE: 0.0024367465681406145
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop')
MSE: 0.002069353591770586
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_total')
MSE: 0.0020719067412828317
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop')
MSE: 0.002080072019503603
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_total')
MSE: 0.00208017193519307
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'NO2_trop', 'NO2_total')
MSE: 0.00147419321977727
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_trop')
MSE: 0.0022362259116024616
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_total')
MSE: 0.002234176571080905
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.001923973806193177
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0020683015992637253
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.0022545872228942844
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002253789422039042
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.002142769218002436
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0022538404860816823
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0024039981157031915
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.002270621924056577
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.0022687585220735815
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.002073937595160491
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002306983772227278
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002356247175951993
Evaluando combinación: ('Precipitation', 'LST', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002502946522924247
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.002286492925762692
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002278156322327502
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.002136863418465164
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0022552620805164573
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0024439001851376033
Evaluando combinación: ('Precipitation', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0026269345691097875
Evaluando combinación: ('Precipitation', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002543283761382305
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.0023772773015142273
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002374884263852571
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.002177814901451094
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0025163905167558988
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0025407123091493633
Evaluando combinación: ('LST', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002781047005689303
Evaluando combinación: ('LST', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0027176963262534174
Evaluando combinación: ('AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0027697985386358876
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop')
MSE: 0.0024333244657409755
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_total')
MSE: 0.002431772724885648
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'NO2_trop', 'NO2_total')
MSE: 0.002309150448477745
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0026041723556547913
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0026083514673370814
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0028608694717270106
Evaluando combinación: ('Precipitation', 'LST', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.00280046947328403
Evaluando combinación: ('Precipitation', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.002856590045553493
Evaluando combinación: ('LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.0031734825325172755
Evaluando combinación: ('Precipitation', 'LST', 'AAI', 'CloudFraction', 'TropopausePressure', 'Year', 'Day', 'NO2_trop', 'NO2_total')
MSE: 0.003274648935294668
La mejor combinación de variables para eliminar es: ('Precipitation', 'LST', 'AAI', 'NO2_trop', 'NO2_total') con un MSE de: 0.0013923663945746177
6.4.1 Drop Variables no importantes¶
Eliminar variables no importantes para reducir la dimensionalidad y mejorar la eficiencia del modelo. Obtengo un modelo mas sencillo
#Drop variables que parece no tener importancia
X_with_imp = train_numericoutliers.drop(columns=['Precipitation', 'LST', 'AAI', 'NO2_trop', 'NO2_total','CloudFraction','GT_NO2'])
#Normalizar data y target separados
X = X_with_imp
y = train_numeric['GT_NO2']
# Normalizar toda la data para un mejor manejo.
scaler_imp_x= MinMaxScaler()
scaler_imp_y=MinMaxScaler()
#Normalizar features
X_scaled_imp = scaler_imp_x.fit_transform(X)
#Normalizar target
y_scaled_imp = scaler_imp_y.fit_transform(y.values.reshape(-1, 1))
# Fit and transform on the selected features
# Convert scaled data back to DataFrame
features_scaled_imp= pd.DataFrame(X_scaled_imp, columns=X.columns)
target_scaled_imp=pd.DataFrame(y_scaled_imp,columns=['GT_NO2'])
X_imp = features_scaled_imp
y_imp = target_scaled_imp
# Divido en training y test con nuevas X, y mantiene igual
X_train_imp, X_test_imp, y_train, y_test = train_test_split (X_imp,
y_imp,
test_size = 0.2,
random_state = 32)
#Pruebo modelo con variables que muestran importancia
# Inicializar modelo
etr_model_importance = ExtraTreesRegressor(
n_estimators=300,
bootstrap=False,
max_depth= None,
min_samples_leaf=1,
min_samples_split=5,
random_state=42).fit(X_train_imp, y_train)
# Realizar validación cruzada
cv = KFold(n_splits=5, shuffle=True, random_state=42)
cv_scores = cross_val_score(etr_model_importance, X_train, y_train, cv=cv, scoring='neg_mean_squared_error')
# Convertir las puntuaciones de MSE negativo a MSE positivo y luego a RMSE
cv_rmse_scores = np.sqrt(-cv_scores)
print(f"Puntuaciones de RMSE en Validación Cruzada (normalizado): {cv_rmse_scores}")
print(f"RMSE Promedio (Normalizado): {cv_rmse_scores.mean()}")
# Ajustar el modelo en todo el conjunto de datos de entrenamiento después de la validación cruzada
etr_model_importance.fit(X_train_imp, y_train)
# Realizar predicciones en el conjunto de prueba
etr_pred_imp= etr_model_importance.predict(X_test_imp)
# Invertir la normalización de las predicciones
etr_pred_imp = scaler_imp_y.inverse_transform(etr_pred_imp.reshape(-1, 1))
# Invertir la normalización de los valores verdaderos del conjunto de prueba
y_test_original = scaler_imp_y.inverse_transform(y_test.values.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, etr_pred_imp)
Puntuaciones de RMSE en Validación Cruzada (normalizado): [0.0414163 0.04207507 0.04220994 0.04123511 0.04149749] RMSE Promedio (Normalizado): 0.041686783478756775 - Mean Absolute Error (MAE): 5.009506538469307 - Mean Squared Error (MSE): 50.05443096781214 - Root Mean Squared Error (RMSE): 7.0749156155965665 - R-squared (R²): 0.8320002668261246
6.5 Mejorar modelo con Bagging¶
Bagging mejora la precisión y la robustez del modelo al reducir la varianza, con la combinación de predicciones de varios modelos entrenados en subconjuntos aleatorios del dataset original, disminuye el riesgo de overfitting.
base_model = ExtraTreesRegressor(n_estimators=100, random_state=42)
bagging_model = BaggingRegressor(base_model,
n_estimators=10, # Number of base models
random_state=42,
n_jobs=-1)
# Train the model
bagging_model.fit(X_train_imp, y_train)
# Make predictions
y_pred = bagging_model.predict(X_test_imp)
# Invertir la normalización de las predicciones para devolverlas a la escala original
y_pred = scaler_imp_y.inverse_transform(y_pred.reshape(-1, 1))
# Remodelar y_test a 2D antes de invertir la normalización
y_test_original = scaler_imp_y.inverse_transform(y_test.values.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, y_pred)
- Mean Absolute Error (MAE): 5.101125726183343 - Mean Squared Error (MSE): 51.95073714391051 - Root Mean Squared Error (RMSE): 7.207685977060218 - R-squared (R²): 0.8256356168752469
El método de bagging no mejoró el modelo.¶
6.6 Intento modelo sin corrección de outliers¶
#Normalizar data y target separados
X = train_numeric.drop('GT_NO2', axis=1)
y = train_numeric['GT_NO2']
# Normalizar toda la data para un mejor manejo.
scaler_out_x= MinMaxScaler()
scaler_out_y=MinMaxScaler()
#Normalizar features
X_scaled_out = scaler_out_x.fit_transform(X)
#Normalizar target
y_scaled_out = scaler_out_y.fit_transform(y.values.reshape(-1, 1))
# Fit and transform on the selected features
# Convert scaled data back to DataFrame
features_scaled_sinoutlier= pd.DataFrame(X_scaled_out, columns=X.columns)
target_scaled_sinoutlier=pd.DataFrame(y_scaled_out,columns=['GT_NO2'])
X_out = features_scaled_sinoutlier
y_out = target_scaled_sinoutlier
# Divido en training y test con nuevas X, y mantiene igual
X_train_out, X_test_out, y_train, y_test = train_test_split (X_out,
y_out,
test_size = 0.2,
random_state = 32)
#Set up PyCaret
model_setup = setup(data=X_out, target=y_out)
#Entrenar modelos
best_model = compare_models()
| Description | Value | |
|---|---|---|
| 0 | Session id | 8947 |
| 1 | Target | Day |
| 2 | Target type | Regression |
| 3 | Original data shape | (82049, 14) |
| 4 | Transformed data shape | (82049, 14) |
| 5 | Transformed train set shape | (57434, 14) |
| 6 | Transformed test set shape | (24615, 14) |
| 7 | Numeric features | 13 |
| 8 | Preprocess | True |
| 9 | Imputation type | simple |
| 10 | Numeric imputation | mean |
| 11 | Categorical imputation | mode |
| 12 | Fold Generator | KFold |
| 13 | Fold Number | 10 |
| 14 | CPU Jobs | -1 |
| 15 | Use GPU | False |
| 16 | Log Experiment | False |
| 17 | Experiment Name | reg-default-name |
| 18 | USI | b900 |
| Model | MAE | MSE | RMSE | R2 | RMSLE | MAPE | TT (Sec) | |
|---|---|---|---|---|---|---|---|---|
| et | Extra Trees Regressor | 0.0785 | 0.0187 | 0.1369 | 0.7817 | 0.0960 | 0.3682 | 1.5660 |
| rf | Random Forest Regressor | 0.0946 | 0.0220 | 0.1482 | 0.7443 | 0.1039 | 0.4532 | 6.4990 |
| xgboost | Extreme Gradient Boosting | 0.1450 | 0.0360 | 0.1898 | 0.5804 | 0.1328 | 0.6895 | 0.1090 |
| dt | Decision Tree Regressor | 0.1017 | 0.0476 | 0.2181 | 0.4461 | 0.1516 | 0.4324 | 0.1460 |
| lightgbm | Light Gradient Boosting Machine | 0.1804 | 0.0484 | 0.2200 | 0.4361 | 0.1541 | 0.9073 | 0.2860 |
| knn | K Neighbors Regressor | 0.1614 | 0.0492 | 0.2219 | 0.4266 | 0.1543 | 0.7697 | 0.0830 |
| gbr | Gradient Boosting Regressor | 0.2326 | 0.0740 | 0.2721 | 0.1379 | 0.1890 | 1.1937 | 2.3500 |
| ada | AdaBoost Regressor | 0.2501 | 0.0837 | 0.2893 | 0.0253 | 0.2006 | 1.2827 | 0.2760 |
| br | Bayesian Ridge | 0.2526 | 0.0854 | 0.2922 | 0.0060 | 0.2025 | 1.2960 | 0.0160 |
| ridge | Ridge Regression | 0.2526 | 0.0854 | 0.2922 | 0.0060 | 0.2025 | 1.2955 | 0.0170 |
| lr | Linear Regression | 0.2526 | 0.0854 | 0.2922 | 0.0060 | 0.2025 | 1.2955 | 0.0230 |
| huber | Huber Regressor | 0.2525 | 0.0854 | 0.2923 | 0.0053 | 0.2025 | 1.2907 | 0.1730 |
| lar | Least Angle Regression | 0.2528 | 0.0855 | 0.2924 | 0.0045 | 0.2026 | 1.2954 | 0.0180 |
| omp | Orthogonal Matching Pursuit | 0.2534 | 0.0858 | 0.2930 | 0.0007 | 0.2031 | 1.3089 | 0.0160 |
| lasso | Lasso Regression | 0.2537 | 0.0859 | 0.2931 | -0.0000 | 0.2032 | 1.3102 | 0.0200 |
| en | Elastic Net | 0.2537 | 0.0859 | 0.2931 | -0.0000 | 0.2032 | 1.3102 | 0.0150 |
| llar | Lasso Least Angle Regression | 0.2537 | 0.0859 | 0.2931 | -0.0000 | 0.2032 | 1.3102 | 0.0150 |
| dummy | Dummy Regressor | 0.2537 | 0.0859 | 0.2931 | -0.0000 | 0.2032 | 1.3102 | 0.0150 |
| par | Passive Aggressive Regressor | 0.3738 | 0.2108 | 0.4408 | -1.4440 | 0.2870 | 1.2978 | 0.0230 |
6.6.1 Tunning de hiperparametros¶
# Definir el modelo
etr = ExtraTreesRegressor(random_state=42)
# Definir los hyperparametros
param_grid = {
'n_estimators': [100, 200, 300],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4],
'bootstrap': [True, False]
}
# GridSearchCV
grid_search = GridSearchCV(estimator=etr, param_grid=param_grid, cv=5, n_jobs=-1, scoring='neg_mean_squared_error')
# Reshape y_train, y_test de ser necesario
y_train = np.ravel(y_train)
y_test = np.ravel(y_test)
# Fit GridSearchCV
grid_search.fit(X_train_out, y_train)
# Print mejores parametros y scroe
print(f"Best Parameters: {grid_search.best_params_}")
print(f"Best Score: {-grid_search.best_score_}")
Best Parameters: {'bootstrap': False, 'max_depth': 30, 'min_samples_leaf': 1, 'min_samples_split': 5, 'n_estimators': 300}
Best Score: 0.0016674871374936114
#Pruebo modelo
# Inicializar modelo
etr_model_outliers = ExtraTreesRegressor(
n_estimators=300,
bootstrap=False,
max_depth= 30,
min_samples_leaf=1,
min_samples_split=5,
random_state=42).fit(X_train_out, y_train)
# Realizar validación cruzada
cv = KFold(n_splits=5, shuffle=True, random_state=42)
cv_scores = cross_val_score(etr_model_outliers, X_train_out, y_train, cv=cv, scoring='neg_mean_squared_error')
# Convertir las puntuaciones de MSE negativo a MSE positivo y luego a RMSE
cv_rmse_scores = np.sqrt(-cv_scores)
print(f"Puntuaciones de RMSE en Validación Cruzada (normalizado): {cv_rmse_scores}")
print(f"RMSE Promedio (Normalizado): {cv_rmse_scores.mean()}")
# Ajustar el modelo en todo el conjunto de datos de entrenamiento después de la validación cruzada
etr_model_outliers.fit(X_train_out, y_train)
# Realizar predicciones en el conjunto de prueba
etr_pred_out= etr_model_outliers.predict(X_test_out)
# Invertir la normalización de las predicciones
etr_pred_out = scaler_out_y.inverse_transform(etr_pred_out.reshape(-1, 1))
# Invertir la normalización de los valores verdaderos del conjunto de prueba
y_test_original = scaler_out_y.inverse_transform(y_test.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, etr_pred_out)
Puntuaciones de RMSE en Validación Cruzada (normalizado): [0.04047413 0.04126437 0.04146651 0.04034064 0.04050344] RMSE Promedio (Normalizado): 0.04080981616631439 - Mean Absolute Error (MAE): 5.358193108115963 - Mean Squared Error (MSE): 57.76301436303403 - Root Mean Squared Error (RMSE): 7.600198310770189 - R-squared (R²): 0.8061276332049647
6.6.2 Selecionar variables importantes¶
# Obtener importancia
importances = etr_model_outliers.feature_importances_
# Crear DataFrame para visualizacion
import pandas as pd
importances_df = pd.DataFrame({
'Feature': X_train_out.columns,
'Importance': importances
}).sort_values(by='Importance', ascending=False)
# Print importancia
print(importances_df)
# Plot
plt.figure(figsize=(10, 6))
plt.barh(importances_df['Feature'], importances_df['Importance'], color='skyblue')
plt.xlabel('Importance')
plt.title('Feature Importance from Extra Trees Regressor Model')
plt.gca().invert_yaxis()
plt.show()
Feature Importance 11 Month 0.180110 8 NO2_trop 0.144976 0 LAT 0.122818 6 NO2_strat 0.122488 7 NO2_total 0.113375 1 LON 0.094282 3 LST 0.050437 12 Day 0.045819 10 Year 0.033810 5 CloudFraction 0.029174 9 TropopausePressure 0.022374 4 AAI 0.020861 2 Precipitation 0.019475
#Partial Dependence Plots
# Especificar los índices de las características que deseas visualizar
features = list(range(X_train_out.shape[1])) # Índices de todas las características en X_train
# Crear Partial Dependence Plots para todas las características
fig, ax = plt.subplots(figsize=(15, 10))
display = PartialDependenceDisplay.from_estimator(etr_model_outliers, X_train_out, features, grid_resolution=50, ax=ax)
# Personalizar el gráfico
plt.suptitle('Partial Dependence Plots', fontsize=16)
plt.subplots_adjust(hspace=0.5, top=0.9) # Ajustar para que el título no se superponga
plt.show()
#Drop variables que parece no tener importancia
X_out_imp = X_out.drop(columns=['Precipitation', 'LST', 'AAI', 'NO2_trop', 'NO2_total','CloudFraction'])
# Divido en training y test con nuevas X, y mantiene igual
X_train_out, X_test_out, y_train, y_test = train_test_split (X_out_imp,
y_out,
test_size = 0.2,
random_state = 32)
#Pruebo modelo
# Inicializar modelo
etr_model_outliers = ExtraTreesRegressor(
n_estimators=300,
bootstrap=False,
max_depth= 30,
min_samples_leaf=1,
min_samples_split=5,
random_state=42).fit(X_train_out, y_train)
# Realizar validación cruzada
cv = KFold(n_splits=5, shuffle=True, random_state=42)
cv_scores = cross_val_score(etr_model_outliers, X_train_out, y_train, cv=cv, scoring='neg_mean_squared_error')
# Convertir las puntuaciones de MSE negativo a MSE positivo y luego a RMSE
cv_rmse_scores = np.sqrt(-cv_scores)
print(f"Puntuaciones de RMSE en Validación Cruzada (normalizado): {cv_rmse_scores}")
print(f"RMSE Promedio (Normalizado): {cv_rmse_scores.mean()}")
# Ajustar el modelo en todo el conjunto de datos de entrenamiento después de la validación cruzada
etr_model_outliers.fit(X_train_out, y_train)
# Realizar predicciones en el conjunto de prueba
etr_pred_out= etr_model_outliers.predict(X_test_out)
# Invertir la normalización de las predicciones
etr_pred_out = scaler_out_y.inverse_transform(etr_pred_out.reshape(-1, 1))
# Invertir la normalización de los valores verdaderos del conjunto de prueba
y_test_original = scaler_out_y.inverse_transform(y_test.values.reshape(-1, 1))
# Calcular las métricas de regresión en la escala original
calculate_regression_metrics(y_test_original, etr_pred_out)
Puntuaciones de RMSE en Validación Cruzada (normalizado): [0.03800033 0.03874696 0.03858784 0.03819873 0.03842396] RMSE Promedio (Normalizado): 0.038391562521174 - Mean Absolute Error (MAE): 4.988491488224833 - Mean Squared Error (MSE): 49.696325881904265 - Root Mean Squared Error (RMSE): 7.049562105684598 - R-squared (R²): 0.8332021895673785
Modelo sin corrección de outliers tiene mejor rendimiento. Modelos tree based tienen menos afectación por outiers¶
6.7 Neural Network¶
Intento con modelos de redes neuronales para ver si sus resultados superan los de los modelos evaluados anteriormente
# Función para construir el modelo utilizando hiperparámetros fijos
def build_model(hp):
model = Sequential()
# Extraer los hiperparámetros
units = hp.get('units') # Número de unidades en cada capa oculta
dropout = hp.get('dropout') # Tasa de abandono (dropout) para la regularización
num_layers = hp.get('num_layers') # Número de capas ocultas
# Capa de entrada
model.add(Dense(units=units, activation='relu', input_shape=(X_train.shape[1],)))
model.add(Dropout(dropout))
# Capas ocultas
for i in range(num_layers):
model.add(Dense(units=units, activation='relu'))
model.add(Dropout(dropout))
# Capa de salida para regresión
model.add(Dense(1, activation='linear'))
# Compilar el modelo con la mejor tasa de aprendizaje encontrada
learning_rate = hp.get('learning_rate')
model.compile(optimizer=Adam(learning_rate=learning_rate), loss='mse', metrics=['mae'])
return model
# Configurar Keras Tuner para buscar los mejores hiperparámetros
tuner = Hyperband(
build_model,
objective='val_loss',
max_epochs=30,
factor=3,
directory='my_dir',
project_name='my_project'
)
Reloading Tuner from my_dir/my_project/tuner0.json
# Callback para detener el entrenamiento de manera anticipada si no hay mejora en la pérdida de validación
early_stopping = EarlyStopping(monitor='val_loss', patience=5)
# Buscar los mejores hiperparámetros utilizando Keras Tuner
tuner.search(X_train, y_train, epochs=50, validation_split=0.2, callbacks=[early_stopping])
# Obtener los mejores hiperparámetros encontrados
best_hps = tuner.get_best_hyperparameters(num_trials=1)[0]
# Definir el modelo utilizando los mejores hiperparámetros encontrados
final_model = tuner.hypermodel.build(best_hps)
# Compilar el modelo con la tasa de aprendizaje óptima encontrada
final_model.compile(optimizer=Adam(learning_rate=best_hps.get('learning_rate')), loss='mse')
# Crear un wrap para el modelo Keras, permite usarlo con scikitlearn
wrapped_model = KerasRegressor(build_fn=create_model, epochs=50, validation_split=0.2, callbacks=[early_stopping])
# Configurar la validación cruzada
kfold = KFold(n_splits=5, shuffle=True, random_state=42)
# Realizar la validación cruzada y calcular el rendimiento del modelo
results_complete = cross_val_score(wrapped_model, X_train, y_train, cv=kfold, scoring='neg_mean_squared_error')
# Mostrar los resultados
print(f"Mean MSE: {-results_complete.mean()}, Standard Deviation: {results_complete.std()}")
Epoch 1/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 1s 325us/step - loss: 0.0050 - mae: 0.0514 - val_loss: 0.0037 - val_mae: 0.0443 Epoch 2/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 285us/step - loss: 0.0039 - mae: 0.0446 - val_loss: 0.0037 - val_mae: 0.0449 Epoch 3/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0037 - mae: 0.0437 - val_loss: 0.0036 - val_mae: 0.0422 Epoch 4/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 287us/step - loss: 0.0036 - mae: 0.0430 - val_loss: 0.0036 - val_mae: 0.0444 Epoch 5/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 289us/step - loss: 0.0034 - mae: 0.0421 - val_loss: 0.0034 - val_mae: 0.0417 Epoch 6/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0035 - mae: 0.0421 - val_loss: 0.0032 - val_mae: 0.0416 Epoch 7/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0033 - mae: 0.0413 - val_loss: 0.0031 - val_mae: 0.0399 Epoch 8/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 307us/step - loss: 0.0032 - mae: 0.0406 - val_loss: 0.0031 - val_mae: 0.0400 Epoch 9/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0031 - mae: 0.0398 - val_loss: 0.0031 - val_mae: 0.0393 Epoch 10/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0031 - mae: 0.0402 - val_loss: 0.0031 - val_mae: 0.0401 Epoch 11/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 291us/step - loss: 0.0030 - mae: 0.0395 - val_loss: 0.0030 - val_mae: 0.0400 Epoch 12/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 287us/step - loss: 0.0030 - mae: 0.0395 - val_loss: 0.0030 - val_mae: 0.0402 Epoch 13/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 288us/step - loss: 0.0030 - mae: 0.0392 - val_loss: 0.0029 - val_mae: 0.0390 Epoch 14/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 280us/step - loss: 0.0029 - mae: 0.0390 - val_loss: 0.0029 - val_mae: 0.0380 Epoch 15/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 286us/step - loss: 0.0029 - mae: 0.0388 - val_loss: 0.0028 - val_mae: 0.0394 Epoch 16/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 325us/step - loss: 0.0029 - mae: 0.0388 - val_loss: 0.0028 - val_mae: 0.0384 Epoch 17/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 303us/step - loss: 0.0029 - mae: 0.0386 - val_loss: 0.0029 - val_mae: 0.0401 Epoch 18/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0028 - mae: 0.0382 - val_loss: 0.0028 - val_mae: 0.0379 Epoch 19/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0028 - mae: 0.0381 - val_loss: 0.0027 - val_mae: 0.0378 Epoch 20/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 301us/step - loss: 0.0029 - mae: 0.0383 - val_loss: 0.0027 - val_mae: 0.0379 Epoch 21/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 301us/step - loss: 0.0028 - mae: 0.0379 - val_loss: 0.0028 - val_mae: 0.0378 Epoch 22/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 303us/step - loss: 0.0027 - mae: 0.0375 - val_loss: 0.0027 - val_mae: 0.0379 Epoch 23/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 305us/step - loss: 0.0027 - mae: 0.0377 - val_loss: 0.0027 - val_mae: 0.0372 Epoch 24/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0027 - mae: 0.0372 - val_loss: 0.0027 - val_mae: 0.0378 Epoch 25/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0028 - mae: 0.0378 - val_loss: 0.0027 - val_mae: 0.0385 Epoch 26/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 292us/step - loss: 0.0027 - mae: 0.0371 - val_loss: 0.0026 - val_mae: 0.0374 Epoch 27/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 296us/step - loss: 0.0026 - mae: 0.0365 - val_loss: 0.0026 - val_mae: 0.0369 Epoch 28/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0026 - mae: 0.0367 - val_loss: 0.0026 - val_mae: 0.0367 Epoch 29/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 294us/step - loss: 0.0026 - mae: 0.0366 - val_loss: 0.0027 - val_mae: 0.0379 Epoch 30/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 292us/step - loss: 0.0026 - mae: 0.0368 - val_loss: 0.0027 - val_mae: 0.0372 Epoch 31/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0026 - mae: 0.0368 - val_loss: 0.0026 - val_mae: 0.0370 Epoch 32/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0026 - mae: 0.0365 - val_loss: 0.0026 - val_mae: 0.0364 Epoch 33/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 294us/step - loss: 0.0025 - mae: 0.0362 - val_loss: 0.0025 - val_mae: 0.0367 Epoch 34/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0025 - mae: 0.0361 - val_loss: 0.0025 - val_mae: 0.0364 Epoch 35/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0026 - mae: 0.0364 - val_loss: 0.0025 - val_mae: 0.0361 Epoch 36/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0025 - mae: 0.0363 - val_loss: 0.0026 - val_mae: 0.0370 Epoch 37/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 314us/step - loss: 0.0025 - mae: 0.0363 - val_loss: 0.0027 - val_mae: 0.0371 Epoch 38/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 304us/step - loss: 0.0025 - mae: 0.0358 - val_loss: 0.0025 - val_mae: 0.0365 Epoch 39/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 301us/step - loss: 0.0025 - mae: 0.0362 - val_loss: 0.0025 - val_mae: 0.0362 Epoch 40/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 303us/step - loss: 0.0025 - mae: 0.0360 - val_loss: 0.0025 - val_mae: 0.0360 Epoch 41/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0025 - mae: 0.0357 - val_loss: 0.0024 - val_mae: 0.0358 Epoch 42/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0025 - mae: 0.0356 - val_loss: 0.0025 - val_mae: 0.0358 Epoch 43/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0025 - mae: 0.0356 - val_loss: 0.0024 - val_mae: 0.0360 Epoch 44/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0024 - mae: 0.0352 - val_loss: 0.0025 - val_mae: 0.0360 Epoch 45/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 300us/step - loss: 0.0024 - mae: 0.0353 - val_loss: 0.0025 - val_mae: 0.0370 Epoch 46/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0024 - mae: 0.0353 - val_loss: 0.0026 - val_mae: 0.0376 Epoch 47/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0024 - mae: 0.0351 - val_loss: 0.0025 - val_mae: 0.0356 Epoch 48/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0024 - mae: 0.0351 - val_loss: 0.0025 - val_mae: 0.0361 411/411 ━━━━━━━━━━━━━━━━━━━━ 0s 228us/step Epoch 1/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 1s 331us/step - loss: 0.0063 - mae: 0.0561 - val_loss: 0.0040 - val_mae: 0.0478 Epoch 2/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 300us/step - loss: 0.0039 - mae: 0.0449 - val_loss: 0.0037 - val_mae: 0.0457 Epoch 3/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0037 - mae: 0.0439 - val_loss: 0.0034 - val_mae: 0.0417 Epoch 4/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0035 - mae: 0.0425 - val_loss: 0.0033 - val_mae: 0.0417 Epoch 5/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 310us/step - loss: 0.0035 - mae: 0.0423 - val_loss: 0.0033 - val_mae: 0.0407 Epoch 6/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 318us/step - loss: 0.0033 - mae: 0.0415 - val_loss: 0.0033 - val_mae: 0.0421 Epoch 7/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 327us/step - loss: 0.0033 - mae: 0.0413 - val_loss: 0.0031 - val_mae: 0.0400 Epoch 8/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 316us/step - loss: 0.0032 - mae: 0.0405 - val_loss: 0.0030 - val_mae: 0.0402 Epoch 9/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0030 - mae: 0.0396 - val_loss: 0.0031 - val_mae: 0.0400 Epoch 10/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 301us/step - loss: 0.0030 - mae: 0.0395 - val_loss: 0.0029 - val_mae: 0.0385 Epoch 11/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 304us/step - loss: 0.0030 - mae: 0.0392 - val_loss: 0.0028 - val_mae: 0.0393 Epoch 12/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 310us/step - loss: 0.0029 - mae: 0.0389 - val_loss: 0.0029 - val_mae: 0.0380 Epoch 13/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 304us/step - loss: 0.0029 - mae: 0.0386 - val_loss: 0.0028 - val_mae: 0.0379 Epoch 14/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 314us/step - loss: 0.0028 - mae: 0.0385 - val_loss: 0.0028 - val_mae: 0.0377 Epoch 15/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 304us/step - loss: 0.0028 - mae: 0.0381 - val_loss: 0.0027 - val_mae: 0.0374 Epoch 16/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 306us/step - loss: 0.0029 - mae: 0.0385 - val_loss: 0.0028 - val_mae: 0.0380 Epoch 17/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 314us/step - loss: 0.0027 - mae: 0.0376 - val_loss: 0.0029 - val_mae: 0.0381 Epoch 18/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 306us/step - loss: 0.0027 - mae: 0.0374 - val_loss: 0.0027 - val_mae: 0.0372 Epoch 19/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 312us/step - loss: 0.0027 - mae: 0.0372 - val_loss: 0.0027 - val_mae: 0.0368 Epoch 20/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 309us/step - loss: 0.0027 - mae: 0.0373 - val_loss: 0.0028 - val_mae: 0.0395 Epoch 21/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 306us/step - loss: 0.0027 - mae: 0.0373 - val_loss: 0.0027 - val_mae: 0.0373 Epoch 22/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 322us/step - loss: 0.0027 - mae: 0.0374 - val_loss: 0.0027 - val_mae: 0.0372 Epoch 23/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 319us/step - loss: 0.0026 - mae: 0.0369 - val_loss: 0.0029 - val_mae: 0.0400 Epoch 24/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 306us/step - loss: 0.0026 - mae: 0.0369 - val_loss: 0.0026 - val_mae: 0.0370 Epoch 25/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 301us/step - loss: 0.0026 - mae: 0.0370 - val_loss: 0.0027 - val_mae: 0.0371 Epoch 26/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 289us/step - loss: 0.0026 - mae: 0.0369 - val_loss: 0.0026 - val_mae: 0.0367 Epoch 27/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 284us/step - loss: 0.0026 - mae: 0.0367 - val_loss: 0.0026 - val_mae: 0.0368 Epoch 28/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 296us/step - loss: 0.0025 - mae: 0.0363 - val_loss: 0.0027 - val_mae: 0.0370 Epoch 29/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 291us/step - loss: 0.0025 - mae: 0.0362 - val_loss: 0.0025 - val_mae: 0.0364 Epoch 30/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0025 - mae: 0.0362 - val_loss: 0.0026 - val_mae: 0.0364 Epoch 31/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 325us/step - loss: 0.0025 - mae: 0.0358 - val_loss: 0.0025 - val_mae: 0.0366 Epoch 32/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 304us/step - loss: 0.0025 - mae: 0.0361 - val_loss: 0.0025 - val_mae: 0.0361 Epoch 33/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0025 - mae: 0.0362 - val_loss: 0.0026 - val_mae: 0.0365 Epoch 34/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0025 - mae: 0.0357 - val_loss: 0.0025 - val_mae: 0.0360 Epoch 35/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 306us/step - loss: 0.0025 - mae: 0.0358 - val_loss: 0.0025 - val_mae: 0.0361 Epoch 36/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0025 - mae: 0.0360 - val_loss: 0.0026 - val_mae: 0.0371 Epoch 37/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 289us/step - loss: 0.0025 - mae: 0.0359 - val_loss: 0.0025 - val_mae: 0.0363 Epoch 38/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 294us/step - loss: 0.0024 - mae: 0.0355 - val_loss: 0.0025 - val_mae: 0.0357 Epoch 39/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 292us/step - loss: 0.0024 - mae: 0.0358 - val_loss: 0.0025 - val_mae: 0.0360 Epoch 40/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 301us/step - loss: 0.0024 - mae: 0.0353 - val_loss: 0.0025 - val_mae: 0.0355 Epoch 41/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 305us/step - loss: 0.0024 - mae: 0.0354 - val_loss: 0.0024 - val_mae: 0.0350 Epoch 42/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0024 - mae: 0.0356 - val_loss: 0.0025 - val_mae: 0.0352 Epoch 43/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0024 - mae: 0.0350 - val_loss: 0.0025 - val_mae: 0.0367 Epoch 44/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0024 - mae: 0.0356 - val_loss: 0.0026 - val_mae: 0.0386 Epoch 45/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 303us/step - loss: 0.0023 - mae: 0.0349 - val_loss: 0.0024 - val_mae: 0.0354 Epoch 46/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 291us/step - loss: 0.0023 - mae: 0.0348 - val_loss: 0.0024 - val_mae: 0.0357 Epoch 47/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0024 - mae: 0.0355 - val_loss: 0.0023 - val_mae: 0.0350 Epoch 48/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 292us/step - loss: 0.0024 - mae: 0.0350 - val_loss: 0.0024 - val_mae: 0.0358 Epoch 49/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 291us/step - loss: 0.0023 - mae: 0.0348 - val_loss: 0.0026 - val_mae: 0.0367 Epoch 50/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0024 - mae: 0.0351 - val_loss: 0.0024 - val_mae: 0.0351 411/411 ━━━━━━━━━━━━━━━━━━━━ 0s 222us/step Epoch 1/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 1s 336us/step - loss: 0.0057 - mae: 0.0544 - val_loss: 0.0040 - val_mae: 0.0477 Epoch 2/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 294us/step - loss: 0.0040 - mae: 0.0455 - val_loss: 0.0036 - val_mae: 0.0439 Epoch 3/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0036 - mae: 0.0431 - val_loss: 0.0034 - val_mae: 0.0417 Epoch 4/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0035 - mae: 0.0422 - val_loss: 0.0033 - val_mae: 0.0403 Epoch 5/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 292us/step - loss: 0.0033 - mae: 0.0415 - val_loss: 0.0032 - val_mae: 0.0400 Epoch 6/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0033 - mae: 0.0413 - val_loss: 0.0037 - val_mae: 0.0460 Epoch 7/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0032 - mae: 0.0403 - val_loss: 0.0030 - val_mae: 0.0392 Epoch 8/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0032 - mae: 0.0401 - val_loss: 0.0031 - val_mae: 0.0404 Epoch 9/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 296us/step - loss: 0.0031 - mae: 0.0397 - val_loss: 0.0031 - val_mae: 0.0413 Epoch 10/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 294us/step - loss: 0.0031 - mae: 0.0398 - val_loss: 0.0030 - val_mae: 0.0390 Epoch 11/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0030 - mae: 0.0391 - val_loss: 0.0028 - val_mae: 0.0382 Epoch 12/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0030 - mae: 0.0392 - val_loss: 0.0028 - val_mae: 0.0381 Epoch 13/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0029 - mae: 0.0387 - val_loss: 0.0029 - val_mae: 0.0385 Epoch 14/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 309us/step - loss: 0.0030 - mae: 0.0388 - val_loss: 0.0030 - val_mae: 0.0401 Epoch 15/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 294us/step - loss: 0.0030 - mae: 0.0392 - val_loss: 0.0028 - val_mae: 0.0375 Epoch 16/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0028 - mae: 0.0382 - val_loss: 0.0028 - val_mae: 0.0380 Epoch 17/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 300us/step - loss: 0.0029 - mae: 0.0384 - val_loss: 0.0028 - val_mae: 0.0382 Epoch 18/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 300us/step - loss: 0.0028 - mae: 0.0380 - val_loss: 0.0029 - val_mae: 0.0381 Epoch 19/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0027 - mae: 0.0376 - val_loss: 0.0028 - val_mae: 0.0396 Epoch 20/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0028 - mae: 0.0377 - val_loss: 0.0026 - val_mae: 0.0372 Epoch 21/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0027 - mae: 0.0376 - val_loss: 0.0027 - val_mae: 0.0373 Epoch 22/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 296us/step - loss: 0.0027 - mae: 0.0375 - val_loss: 0.0026 - val_mae: 0.0367 Epoch 23/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0027 - mae: 0.0372 - val_loss: 0.0027 - val_mae: 0.0375 Epoch 24/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0027 - mae: 0.0372 - val_loss: 0.0027 - val_mae: 0.0389 Epoch 25/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0026 - mae: 0.0368 - val_loss: 0.0026 - val_mae: 0.0365 Epoch 26/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0027 - mae: 0.0372 - val_loss: 0.0027 - val_mae: 0.0388 Epoch 27/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 312us/step - loss: 0.0026 - mae: 0.0370 - val_loss: 0.0026 - val_mae: 0.0367 Epoch 28/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 296us/step - loss: 0.0026 - mae: 0.0368 - val_loss: 0.0026 - val_mae: 0.0375 Epoch 29/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 322us/step - loss: 0.0026 - mae: 0.0364 - val_loss: 0.0026 - val_mae: 0.0368 Epoch 30/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 296us/step - loss: 0.0025 - mae: 0.0363 - val_loss: 0.0026 - val_mae: 0.0369 411/411 ━━━━━━━━━━━━━━━━━━━━ 0s 214us/step Epoch 1/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 1s 336us/step - loss: 0.0052 - mae: 0.0524 - val_loss: 0.0037 - val_mae: 0.0447 Epoch 2/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 296us/step - loss: 0.0038 - mae: 0.0441 - val_loss: 0.0034 - val_mae: 0.0429 Epoch 3/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0037 - mae: 0.0433 - val_loss: 0.0035 - val_mae: 0.0419 Epoch 4/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 294us/step - loss: 0.0035 - mae: 0.0425 - val_loss: 0.0034 - val_mae: 0.0414 Epoch 5/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0035 - mae: 0.0421 - val_loss: 0.0033 - val_mae: 0.0404 Epoch 6/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0033 - mae: 0.0413 - val_loss: 0.0031 - val_mae: 0.0399 Epoch 7/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0033 - mae: 0.0409 - val_loss: 0.0032 - val_mae: 0.0405 Epoch 8/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0031 - mae: 0.0401 - val_loss: 0.0031 - val_mae: 0.0414 Epoch 9/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0031 - mae: 0.0400 - val_loss: 0.0030 - val_mae: 0.0388 Epoch 10/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0032 - mae: 0.0402 - val_loss: 0.0029 - val_mae: 0.0388 Epoch 11/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0030 - mae: 0.0396 - val_loss: 0.0030 - val_mae: 0.0393 Epoch 12/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0030 - mae: 0.0397 - val_loss: 0.0029 - val_mae: 0.0386 Epoch 13/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0030 - mae: 0.0393 - val_loss: 0.0028 - val_mae: 0.0382 Epoch 14/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0029 - mae: 0.0392 - val_loss: 0.0028 - val_mae: 0.0381 Epoch 15/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 300us/step - loss: 0.0029 - mae: 0.0385 - val_loss: 0.0028 - val_mae: 0.0381 Epoch 16/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 300us/step - loss: 0.0029 - mae: 0.0386 - val_loss: 0.0027 - val_mae: 0.0380 Epoch 17/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0028 - mae: 0.0381 - val_loss: 0.0027 - val_mae: 0.0375 Epoch 18/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 314us/step - loss: 0.0028 - mae: 0.0379 - val_loss: 0.0034 - val_mae: 0.0418 Epoch 19/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 307us/step - loss: 0.0028 - mae: 0.0383 - val_loss: 0.0028 - val_mae: 0.0388 Epoch 20/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0028 - mae: 0.0384 - val_loss: 0.0027 - val_mae: 0.0373 Epoch 21/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0028 - mae: 0.0379 - val_loss: 0.0027 - val_mae: 0.0388 Epoch 22/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0027 - mae: 0.0375 - val_loss: 0.0027 - val_mae: 0.0374 Epoch 23/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0027 - mae: 0.0375 - val_loss: 0.0026 - val_mae: 0.0374 Epoch 24/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0026 - mae: 0.0370 - val_loss: 0.0026 - val_mae: 0.0363 Epoch 25/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0027 - mae: 0.0373 - val_loss: 0.0025 - val_mae: 0.0363 Epoch 26/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 306us/step - loss: 0.0026 - mae: 0.0366 - val_loss: 0.0026 - val_mae: 0.0364 Epoch 27/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 306us/step - loss: 0.0027 - mae: 0.0375 - val_loss: 0.0026 - val_mae: 0.0381 Epoch 28/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0026 - mae: 0.0370 - val_loss: 0.0026 - val_mae: 0.0377 Epoch 29/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 304us/step - loss: 0.0026 - mae: 0.0367 - val_loss: 0.0027 - val_mae: 0.0379 Epoch 30/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 301us/step - loss: 0.0026 - mae: 0.0367 - val_loss: 0.0027 - val_mae: 0.0382 411/411 ━━━━━━━━━━━━━━━━━━━━ 0s 226us/step Epoch 1/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 1s 328us/step - loss: 0.0050 - mae: 0.0512 - val_loss: 0.0039 - val_mae: 0.0468 Epoch 2/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 302us/step - loss: 0.0037 - mae: 0.0444 - val_loss: 0.0035 - val_mae: 0.0427 Epoch 3/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 303us/step - loss: 0.0035 - mae: 0.0429 - val_loss: 0.0036 - val_mae: 0.0446 Epoch 4/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 303us/step - loss: 0.0035 - mae: 0.0425 - val_loss: 0.0033 - val_mae: 0.0413 Epoch 5/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0034 - mae: 0.0417 - val_loss: 0.0033 - val_mae: 0.0417 Epoch 6/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 297us/step - loss: 0.0034 - mae: 0.0416 - val_loss: 0.0033 - val_mae: 0.0407 Epoch 7/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 304us/step - loss: 0.0032 - mae: 0.0407 - val_loss: 0.0031 - val_mae: 0.0397 Epoch 8/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0032 - mae: 0.0405 - val_loss: 0.0030 - val_mae: 0.0392 Epoch 9/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 303us/step - loss: 0.0031 - mae: 0.0402 - val_loss: 0.0030 - val_mae: 0.0395 Epoch 10/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 312us/step - loss: 0.0031 - mae: 0.0396 - val_loss: 0.0031 - val_mae: 0.0406 Epoch 11/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 307us/step - loss: 0.0030 - mae: 0.0393 - val_loss: 0.0029 - val_mae: 0.0384 Epoch 12/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0029 - mae: 0.0392 - val_loss: 0.0029 - val_mae: 0.0386 Epoch 13/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0029 - mae: 0.0389 - val_loss: 0.0030 - val_mae: 0.0398 Epoch 14/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 298us/step - loss: 0.0030 - mae: 0.0389 - val_loss: 0.0029 - val_mae: 0.0390 Epoch 15/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0028 - mae: 0.0382 - val_loss: 0.0028 - val_mae: 0.0381 Epoch 16/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0028 - mae: 0.0384 - val_loss: 0.0028 - val_mae: 0.0381 Epoch 17/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0028 - mae: 0.0382 - val_loss: 0.0030 - val_mae: 0.0404 Epoch 18/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0027 - mae: 0.0376 - val_loss: 0.0029 - val_mae: 0.0378 Epoch 19/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 291us/step - loss: 0.0027 - mae: 0.0377 - val_loss: 0.0027 - val_mae: 0.0373 Epoch 20/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0027 - mae: 0.0377 - val_loss: 0.0027 - val_mae: 0.0383 Epoch 21/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 304us/step - loss: 0.0027 - mae: 0.0377 - val_loss: 0.0028 - val_mae: 0.0381 Epoch 22/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 315us/step - loss: 0.0027 - mae: 0.0375 - val_loss: 0.0027 - val_mae: 0.0372 Epoch 23/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0027 - mae: 0.0374 - val_loss: 0.0028 - val_mae: 0.0382 Epoch 24/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 289us/step - loss: 0.0027 - mae: 0.0372 - val_loss: 0.0028 - val_mae: 0.0383 Epoch 25/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 287us/step - loss: 0.0026 - mae: 0.0371 - val_loss: 0.0027 - val_mae: 0.0370 Epoch 26/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 288us/step - loss: 0.0026 - mae: 0.0371 - val_loss: 0.0027 - val_mae: 0.0376 Epoch 27/50 1313/1313 ━━━━━━━━━━━━━━━━━━━━ 0s 287us/step - loss: 0.0026 - mae: 0.0370 - val_loss: 0.0027 - val_mae: 0.0374 411/411 ━━━━━━━━━━━━━━━━━━━━ 0s 213us/step Mean MSE: 0.002652587326792442, Standard Deviation: 0.0001275440467535271
# Entrenar el modelo final con todos los datos de training
final_model.fit(X_train, y_train, epochs=50, validation_split=0.2)
# Realizar predicciones
NN_pred = final_model.predict(X_test)
#Volver a valores originales, no noramlizados
NN_pred = scaler_train_y.inverse_transform(NN_pred.reshape(-1, 1))
y_test_original = scaler_train_y.inverse_transform(y_test.values.reshape(-1, 1))
# Calcular resultados
calculate_regression_metrics(y_test_original, NN_pred)
Epoch 1/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 287us/step - loss: 0.0022 - val_loss: 0.0022 Epoch 2/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 269us/step - loss: 0.0022 - val_loss: 0.0022 Epoch 3/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 284us/step - loss: 0.0022 - val_loss: 0.0023 Epoch 4/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 283us/step - loss: 0.0022 - val_loss: 0.0022 Epoch 5/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 281us/step - loss: 0.0022 - val_loss: 0.0022 Epoch 6/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 280us/step - loss: 0.0022 - val_loss: 0.0023 Epoch 7/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 278us/step - loss: 0.0022 - val_loss: 0.0023 Epoch 8/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 277us/step - loss: 0.0021 - val_loss: 0.0023 Epoch 9/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 277us/step - loss: 0.0022 - val_loss: 0.0023 Epoch 10/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 282us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 11/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 281us/step - loss: 0.0022 - val_loss: 0.0022 Epoch 12/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 278us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 13/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 280us/step - loss: 0.0022 - val_loss: 0.0022 Epoch 14/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 284us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 15/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 285us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 16/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 285us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 17/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 282us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 18/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 282us/step - loss: 0.0022 - val_loss: 0.0022 Epoch 19/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 288us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 20/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 280us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 21/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 299us/step - loss: 0.0021 - val_loss: 0.0023 Epoch 22/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 1s 298us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 23/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 291us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 24/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0021 - val_loss: 0.0023 Epoch 25/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 291us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 26/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 292us/step - loss: 0.0021 - val_loss: 0.0023 Epoch 27/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 286us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 28/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 280us/step - loss: 0.0021 - val_loss: 0.0023 Epoch 29/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 284us/step - loss: 0.0021 - val_loss: 0.0023 Epoch 30/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 288us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 31/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 280us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 32/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 280us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 33/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 280us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 34/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 279us/step - loss: 0.0020 - val_loss: 0.0022 Epoch 35/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 279us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 36/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 276us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 37/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 286us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 38/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 296us/step - loss: 0.0021 - val_loss: 0.0021 Epoch 39/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 1s 300us/step - loss: 0.0021 - val_loss: 0.0022 Epoch 40/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 282us/step - loss: 0.0020 - val_loss: 0.0021 Epoch 41/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 277us/step - loss: 0.0020 - val_loss: 0.0021 Epoch 42/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 279us/step - loss: 0.0020 - val_loss: 0.0021 Epoch 43/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 281us/step - loss: 0.0020 - val_loss: 0.0021 Epoch 44/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 278us/step - loss: 0.0020 - val_loss: 0.0021 Epoch 45/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 1s 304us/step - loss: 0.0020 - val_loss: 0.0021 Epoch 46/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 1s 300us/step - loss: 0.0020 - val_loss: 0.0021 Epoch 47/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 1s 311us/step - loss: 0.0020 - val_loss: 0.0022 Epoch 48/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 290us/step - loss: 0.0020 - val_loss: 0.0021 Epoch 49/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 295us/step - loss: 0.0020 - val_loss: 0.0022 Epoch 50/50 1641/1641 ━━━━━━━━━━━━━━━━━━━━ 0s 293us/step - loss: 0.0020 - val_loss: 0.0022 513/513 ━━━━━━━━━━━━━━━━━━━━ 0s 192us/step - Mean Absolute Error (MAE): 6.665860132480591 - Mean Squared Error (MSE): 83.39813445680186 - Root Mean Squared Error (RMSE): 9.13225790573185 - R-squared (R²): 0.7200874315212678
El resultado de ETR es mejor. El valor de MSE con Neural Network es mayor. Por lo tanto el mejor modelo final es el ETR.¶
Para este dataset en especifico no es viable llevar a cabo un analisis utilizando modelos de timeseries, ya que se tiene varias entradas de datos por cada día, y un modelo de timeseries implica tener un dato por día. Una posible via para llevar a cabo el analisis sería utilizar un promedio o el valor máximo por dia, pero esto implicaria agregarle sesgo a la data proporcionada. Es por esto que se decidió utilizar modelos de machine learning y redes neuronales.¶
7. Set de Testing¶
Aplico mismos pasos que se aplicó a data de training.
#Cargo archivo de prueba
test = pd.read_csv('/Users/carlazurcher/Downloads/geoai-ground-level-no2-estimation-challenge20240612-4943-16iro0r/Test.csv')
test
| ID_Zindi | Date | ID | LAT | LON | Precipitation | LST | AAI | CloudFraction | NO2_strat | NO2_total | NO2_trop | TropopausePressure | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ID_2MYNQS | 1/1/19 | PD03 | 45.289376 | 11.642394 | 3.277529 | NaN | -0.313361 | 0.771456 | 0.000024 | 0.000075 | NaN | 14440.02819 |
| 1 | ID_P4U5WU | 1/1/19 | TV03 | 45.836941 | 12.510362 | 0.000000 | NaN | -0.229512 | 0.398208 | 0.000023 | 0.000120 | NaN | 14434.04790 |
| 2 | ID_U4KWPK | 1/1/19 | X5561 | 45.582894 | 8.842165 | 0.000000 | 282.98 | -0.470822 | 0.153694 | 0.000023 | 0.000171 | 0.000148 | 14427.42478 |
| 3 | ID_QGSNTZ | 1/1/19 | X5953 | 45.131947 | 10.015742 | 1.928031 | NaN | 0.132952 | 0.756917 | 0.000024 | 0.000266 | NaN | 14443.09006 |
| 4 | ID_GHSZ6K | 1/1/19 | X6701 | 45.186329 | 9.146666 | 0.000000 | NaN | -0.198272 | 0.678858 | 0.000023 | 0.000149 | NaN | 14440.85840 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 6571 | ID_GUSXU9 | 12/31/21 | TV03 | 45.836941 | 12.510362 | 0.000000 | 282.58 | -0.013364 | 0.000000 | 0.000032 | 0.000135 | 0.000103 | 13060.46860 |
| 6572 | ID_GMVEG1 | 12/31/21 | X5561 | 45.582894 | 8.842165 | 0.000000 | 285.12 | -0.412887 | 0.002098 | 0.000031 | 0.000201 | 0.000171 | 13056.11764 |
| 6573 | ID_GD6HNP | 12/31/21 | X5953 | 45.131947 | 10.015742 | 0.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 6574 | ID_J7YW1Y | 12/31/21 | X6701 | 45.186329 | 9.146666 | 0.000000 | NaN | -1.025128 | 0.476947 | 0.000031 | 0.000751 | NaN | 13063.22260 |
| 6575 | ID_I4E04N | 12/31/21 | X6877 | 45.151743 | 10.781408 | 0.000000 | 273.42 | -0.844936 | 0.460769 | 0.000032 | 0.000488 | NaN | 13064.08868 |
6576 rows × 13 columns
#Verifico informacion basica
test.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 6576 entries, 0 to 6575 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID_Zindi 6576 non-null object 1 Date 6576 non-null object 2 ID 6576 non-null object 3 LAT 6576 non-null float64 4 LON 6576 non-null float64 5 Precipitation 6576 non-null float64 6 LST 3595 non-null float64 7 AAI 5708 non-null float64 8 CloudFraction 5708 non-null float64 9 NO2_strat 5708 non-null float64 10 NO2_total 5708 non-null float64 11 NO2_trop 3998 non-null float64 12 TropopausePressure 5708 non-null float64 dtypes: float64(10), object(3) memory usage: 668.0+ KB
#Corregir formato de fecha mixto (algunos poseen / otros -)
test['Date'] = test['Date'].str.replace('/', '-')
#Corregir fecha a datetime
test['Date']=pd.to_datetime(test['Date'],format='%m-%d-%y')
test['Date']
0 2019-01-01
1 2019-01-01
2 2019-01-01
3 2019-01-01
4 2019-01-01
...
6571 2021-12-31
6572 2021-12-31
6573 2021-12-31
6574 2021-12-31
6575 2021-12-31
Name: Date, Length: 6576, dtype: datetime64[ns]
# Extraer año, mes, dia.
test['Year'] = test['Date'].dt.year
test['Month'] = test['Date'].dt.month
test['Day'] = test['Date'].dt.day
#Paso ID a index
test.set_index('ID_Zindi', inplace=True)
test.head()
| Date | ID | LAT | LON | Precipitation | LST | AAI | CloudFraction | NO2_strat | NO2_total | NO2_trop | TropopausePressure | Year | Month | Day | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ID_Zindi | |||||||||||||||
| ID_2MYNQS | 2019-01-01 | PD03 | 45.289376 | 11.642394 | 3.277529 | NaN | -0.313361 | 0.771456 | 0.000024 | 0.000075 | NaN | 14440.02819 | 2019 | 1 | 1 |
| ID_P4U5WU | 2019-01-01 | TV03 | 45.836941 | 12.510362 | 0.000000 | NaN | -0.229512 | 0.398208 | 0.000023 | 0.000120 | NaN | 14434.04790 | 2019 | 1 | 1 |
| ID_U4KWPK | 2019-01-01 | X5561 | 45.582894 | 8.842165 | 0.000000 | 282.98 | -0.470822 | 0.153694 | 0.000023 | 0.000171 | 0.000148 | 14427.42478 | 2019 | 1 | 1 |
| ID_QGSNTZ | 2019-01-01 | X5953 | 45.131947 | 10.015742 | 1.928031 | NaN | 0.132952 | 0.756917 | 0.000024 | 0.000266 | NaN | 14443.09006 | 2019 | 1 | 1 |
| ID_GHSZ6K | 2019-01-01 | X6701 | 45.186329 | 9.146666 | 0.000000 | NaN | -0.198272 | 0.678858 | 0.000023 | 0.000149 | NaN | 14440.85840 | 2019 | 1 | 1 |
#Agrupo variables numericas
test_numeric= test.select_dtypes(include=['number'])
test_numeric
| LAT | LON | Precipitation | LST | AAI | CloudFraction | NO2_strat | NO2_total | NO2_trop | TropopausePressure | Year | Month | Day | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ID_Zindi | |||||||||||||
| ID_2MYNQS | 45.289376 | 11.642394 | 3.277529 | NaN | -0.313361 | 0.771456 | 0.000024 | 0.000075 | NaN | 14440.02819 | 2019 | 1 | 1 |
| ID_P4U5WU | 45.836941 | 12.510362 | 0.000000 | NaN | -0.229512 | 0.398208 | 0.000023 | 0.000120 | NaN | 14434.04790 | 2019 | 1 | 1 |
| ID_U4KWPK | 45.582894 | 8.842165 | 0.000000 | 282.98 | -0.470822 | 0.153694 | 0.000023 | 0.000171 | 0.000148 | 14427.42478 | 2019 | 1 | 1 |
| ID_QGSNTZ | 45.131947 | 10.015742 | 1.928031 | NaN | 0.132952 | 0.756917 | 0.000024 | 0.000266 | NaN | 14443.09006 | 2019 | 1 | 1 |
| ID_GHSZ6K | 45.186329 | 9.146666 | 0.000000 | NaN | -0.198272 | 0.678858 | 0.000023 | 0.000149 | NaN | 14440.85840 | 2019 | 1 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| ID_GUSXU9 | 45.836941 | 12.510362 | 0.000000 | 282.58 | -0.013364 | 0.000000 | 0.000032 | 0.000135 | 0.000103 | 13060.46860 | 2021 | 12 | 31 |
| ID_GMVEG1 | 45.582894 | 8.842165 | 0.000000 | 285.12 | -0.412887 | 0.002098 | 0.000031 | 0.000201 | 0.000171 | 13056.11764 | 2021 | 12 | 31 |
| ID_GD6HNP | 45.131947 | 10.015742 | 0.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 2021 | 12 | 31 |
| ID_J7YW1Y | 45.186329 | 9.146666 | 0.000000 | NaN | -1.025128 | 0.476947 | 0.000031 | 0.000751 | NaN | 13063.22260 | 2021 | 12 | 31 |
| ID_I4E04N | 45.151743 | 10.781408 | 0.000000 | 273.42 | -0.844936 | 0.460769 | 0.000032 | 0.000488 | NaN | 13064.08868 | 2021 | 12 | 31 |
6576 rows × 13 columns
#Drop las mismas variables que en el de training
test_numeric=test_numeric.drop(columns=['Precipitation', 'LST', 'AAI', 'NO2_trop', 'NO2_total','CloudFraction'])
#Ddeteccion de missings
#Aplico formula
missing_proport(test_numeric)
NO2_strat 13.199513 TropopausePressure 13.199513 LAT 0.000000 LON 0.000000 Year 0.000000 Month 0.000000 Day 0.000000 dtype: float64
# Selecciono las variables a imputar
features = ['NO2_strat','TropopausePressure']
# Reseteo index antes de normalizar
test_numeric.reset_index(inplace=True)
# Normalizar toda la data para un mejor manejo.
scaler = MinMaxScaler()
test_numeric_scaled = scaler.fit_transform(test[features]) # Fit and transform on the selected features
# Convertir el array normalizado a dataframe
test_numeric_scaled = pd.DataFrame(test_numeric_scaled, columns=features)
# Usar la data normalizada para imputaacion
imputer_test = IterativeImputer(estimator=BayesianRidge())
df_imputed_test= imputer_test.fit_transform(test_numeric_scaled)
# Convertir data imputada de vuelta a DataFrame
df_imputed_test = pd.DataFrame(df_imputed_test, columns=features)
# Revertir la normalizacion
df_imputed_test_original_scale = pd.DataFrame(scaler.inverse_transform(df_imputed_test), columns=features)
# Reemplazar valores en dataframe
test_numeric.loc[:, features] = df_imputed_test_original_scale
# 'ID_Zindi' como index
test_numeric.set_index('ID_Zindi', inplace=True)
#Verifico Nan otra vez
missing_proport(test_numeric)
LAT 0.0 LON 0.0 NO2_strat 0.0 TropopausePressure 0.0 Year 0.0 Month 0.0 Day 0.0 dtype: float64
#Normalizar data
test_scaled = scaler_out_x.fit_transform(test_numeric)
test_scaled_df= pd.DataFrame(test_scaled, columns=test_numeric.columns,index=test_numeric.index)
7.1 ETR Model Predicciones¶
Predicciones hechas con modelo ETR sin corrección de outilers
# Generar las predicciones con el mejor modelo entrenado
etr_scaled_predictions = etr_model_outliers.predict(test_scaled_df)
# Transformarlo a un array de 2D
etr_scaled_predictions = etr_scaled_predictions.reshape(-1, 1)
# Revertir a escala original
etr_predictions = scaler_out_y.inverse_transform(etr_scaled_predictions)
# Convertir predicciones a DataFrame
etr_predictions_df = pd.DataFrame(etr_predictions, index=test_scaled_df.index, columns=['GT_NO2'])
# Mostrar predicciones
print(etr_predictions_df)
GT_NO2 ID_Zindi ID_2MYNQS 45.810588 ID_P4U5WU 34.606269 ID_U4KWPK 54.306910 ID_QGSNTZ 40.039354 ID_GHSZ6K 38.663667 ... ... ID_GUSXU9 35.396465 ID_GMVEG1 28.958234 ID_GD6HNP 27.991938 ID_J7YW1Y 33.290215 ID_I4E04N 32.031831 [6576 rows x 1 columns]
# Exporto predicciónes a CSV
etr_predictions_df.to_csv('ETR.csv')
7.2 NN Model predicciones¶
Predicciones con modelo de Neural Network
# Generar las predicciones con el mejor modelo entrenado
NN_scaled_predictions = final_model.predict(test_scaled_df)
# Transformarlo a un array de 2D
NN_scaled_predictions = NN_scaled_predictions.reshape(-1, 1)
# Revertir a escala original
NN_predictions = scaler_train_y.inverse_transform(NN_scaled_predictions)
# Convertir predicciones a DataFrame
NN_df = pd.DataFrame(NN_predictions, index=test_scaled_df.index, columns=['GT_NO2'])
# Mostrar predicciones
print(NN_df)
206/206 ━━━━━━━━━━━━━━━━━━━━ 0s 213us/step GT_NO2 ID_Zindi ID_2MYNQS 20.403675 ID_P4U5WU 32.795277 ID_U4KWPK 38.553070 ID_QGSNTZ 26.489946 ID_GHSZ6K 30.378811 ... ... ID_GUSXU9 37.008095 ID_GMVEG1 34.690079 ID_GD6HNP 29.328226 ID_J7YW1Y 36.333340 ID_I4E04N 27.617683 [6576 rows x 1 columns]
# Exporto predicciónes a CSV
NN_df.to_csv('NN_predictions.csv', index=True)
8. Guardo informacion del mejor modelo de ETR para aplicacion¶
import joblib
# Save models for online app
#ETR MODEL
joblib.dump(etr_model_outliers, 'etr_model.pkl')
#Scaler y
joblib.dump(scaler_out_y, 'scaler_train_Y.pkl')
#Scaler x
joblib.dump(scaler_out_x, 'scaler_train_X.pkl')
['scaler_train_X.pkl']